【问题标题】:mysql, how to select tree without nodemysql,如何选择没有节点的树
【发布时间】:2014-04-17 08:50:29
【问题描述】:

我确定这是一项简单的任务,但我被困了几天:我有简化表:

插入`tree`(`fruit`,`tree`)值 ('苹果','A'), ('梨','A'), ('苹果', 'B'), ('香蕉', 'B');

例如,我需要明确说明我需要什么水果和不需要什么水果,所以我是这样的:

IN ('apple', 'banana') && NOT IN('pear')

应该返回“B”,因为我们得到了有苹果和香蕉的树,没有梨

有什么想法吗?谢谢。

【问题讨论】:

  • 当我读到你的问题时,你想要结果 A 和 B,是吗?
  • 我只需要B(没有梨的树)
  • @smidhonza 我是否应该理解您可能想要指定“必须拥有”“不应该拥有”集?还是我们“可以拥有”的第一套?
  • 我需要明确说明树必须有哪些果实,哪些不能有。我没有意识到我的问题不是很清楚,很抱歉。

标签: mysql sql


【解决方案1】:

简单的选择应该与 NOT EXISTS 检查一起使用。

SELECT t1.tree FROM tree t1 WHERE t1.fruit='apple' 
AND NOT EXISTS 
           (SELECT 1 
            FROM tree t2 
             WHERE t1.tree=t2.tree and t2.fruit='pear');

【讨论】:

    【解决方案2】:

    如果您只想要样本中的“B”:

    select t.fruit, t.tree
    from tree t
    where t.fruit = 'apple'
    and not exists (select null
                      from tree t1
                      where t1.tree = t.tree
                      and t.fruit = 'pear');
    

    如果你有

    INSERT INTO `tree` (`fruit`, `tree`) VALUES
    ('apple',   'A'),
    ('pear',    'A'),
    ('apple',   'B')
    ('banana', 'B')
    

    你只会得到apple-B一行

    如果您想扩展您的样本,并获取所有至少有 1 个苹果且没有梨,但还有香蕉的树,例如

    select t.fruit, t.tree
    from tree t
    where not exists (select null
                          from tree t1
                          where t1.tree = t.tree
                          and t.fruit = 'pear')
    and exists        (select null
                          from tree t1
                          where t1.tree = t.tree
                          and t.fruit = 'apple');
    

    然后你会得到apple-Bbanana-B

    【讨论】:

      【解决方案3】:

      虽然以前的答案是完全正确的,但我认为您可以使用 LEFT JOIN 尝试没有嵌套 SQL 的 SQL

      SELECT A.tree FROM
          tree A LEFT JOIN tree B
      ON
          A.tree = B.tree AND
          B.fruit = 'pear' 
      WHERE 
          B.fruit IS NULL AND
          A.fruit = 'apple';
      

      对于“树”列不匹配或第二个水果不是梨的treetable 内部笛卡尔积的任何组合,ON 条件将使所有 B.* 字段为 NULL。 WHERE 条件将过滤结果以仅包含第二组为空且果实为苹果的树。

      结合你得到的两个条件:所有那些有苹果但没有梨的树。

      编辑:(在您的问题编辑之后)

      只要你没有重复的树果对,你可以试试:

      SELECT A.tree FROM
          tree A LEFT JOIN tree B
      ON
          A.tree = B.tree AND
          B.fruit IN ('pear') #Can't have
      WHERE 
          B.fruit IS NULL AND
          A.fruit IN ('apple','banana') # Must have           <---\
      GROUP BY A.tree HAVING COUNT(1) = 2; #Number of elements in /
      

      【讨论】:

      • @smidhonza 如果“必须拥有”设置为“可以拥有”,这将更容易和更清晰,因为您可以删除我不太喜欢的GROUP BY HAVING COUNT 技巧。您还有另一个选择,就是将我的第一个查询嵌套到另一个查询中,但我也不喜欢它
      【解决方案4】:

      您还可以在 HAVING 子句中使用分组并检查聚合值,如下所示:

      SELECT   tree
      FROM     tree
      GROUP BY tree
      HAVING   MAX(fruit IN ('apple', 'banana')) = 1
         AND   MAX(fruit IN ('pear')           ) = 0
      ;
      

      同一方法的更独立于平台的版本将涉及 CASE:

      SELECT   tree
      FROM     tree
      GROUP BY tree
      HAVING   MAX(CASE WHEN fruit IN ('apple', 'banana') THEN 1 ELSE 0 END) = 1
         AND   MAX(CASE WHEN fruit IN ('pear')            THEN 1 ELSE 0 END) = 0
      ;
      

      要指定树必须同时具有applebanana,请再添加一个条件:

      AND COUNT(*) = 2
      

      如果允许一棵树有重复的水果条目,请改用此条件:

      AND COUNT(DISTINCT fruit) = 2
      

      或者,您可以为每个允许的水果指定单独的条件,如下所示:

      SELECT   tree
      FROM     tree
      GROUP BY tree
      HAVING   MAX(fruit = 'apple'  ) = 1
         AND   MAX(fruit = 'banana' ) = 1
         AND   MAX(fruit IN ('pear')) = 0
      ;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-12
        • 1970-01-01
        • 2010-11-22
        相关资源
        最近更新 更多