【问题标题】:SQL query to only get results where all requested 2-column matches occurSQL 查询仅获取所有请求的 2 列匹配发生的结果
【发布时间】:2018-06-01 19:22:55
【问题描述】:

我想得到一个结果,其中可以为第 2 列和第 3 列的三个(或更多)组合(成对?)找到第 1 列的值示例...这是一个包含 3 列的假设表:

水果 |特质 |描述
-------------------------------------------
苹果 |颜色 |红色的
苹果 |形状 |圆形的
梨 |表面 |光滑的
梨 |茎|红色的
葡萄| 高分辨率照片| CLIPARTO形状 |圆形的
葡萄| 高分辨率照片| CLIPARTO颜色 |红色的
葡萄| 高分辨率照片| CLIPARTO表面 |流畅

我想找到形状=圆形、颜色=红色、表面=光滑的水果。上表中的结果应该是“葡萄”,但我试图找出正确的 sql 查询,我无法缩小范围。我买苹果,因为它是红色的,我买梨,因为它很光滑。但我不想要那些。我想要一种水果,它可以显示所有三个特征/描述的值。

我已经走到了这一步,认为有一种方法可以使用组,我使用了子查询 - 认为这会给我一种要求的方法。但它仍然没有给我带来“葡萄”的结果。

 SELECT fruit /* DISTINCT ?*/ FROM table1 WHERE fruit 
 IN  (SELECT fruit FROM table1 WHERE trait = 'shape' AND described = 'round')
 AND (SELECT fruit FROM table1 WHERE trait = 'color' AND described = 'red')
 AND (SELECT fruit FROM table1 WHERE trait = 'surface' AND described = 'smooth')     
 HAVING count(fruit) = 3   /* or whatever number of trait/described combos were searched for */

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    你是如此接近。只需继续从您的子句中选择水果,不要担心计数 - 您使用 DISTINCT 也是正确的

    SELECT DISTINCT FRUIT FROM Table1 
    WHERE FRUIT IN (SELECT FRUIT FROM Table1 WHERE TRAIT = 'shape' AND DESCRIBED = 'round')
    AND FRUIT IN (SELECT FRUIT FROM Table1 WHERE TRAIT = 'color' AND DESCRIBED = 'red')
    AND FRUIT IN (SELECT FRUIT FROM Table1 WHERE TRAIT = 'surface' AND DESCRIBED = 'smooth')
    

    您可以在 SQL Fiddle I used 上进行测试

    【讨论】:

      【解决方案2】:

      我会这样做:

      SELECT fruit 
      FROM table1 
      WHERE (trait, described) IN ( ('shape', 'round'), ('color', 'red'), ('surface', 'smooth') )  
      GROUP BY fruit 
      HAVING count(fruit) = 3  ;
      

      这比具有不必要子查询的查询更易于读取、写入和维护。至于性能,从性能角度来看,SELECT DISTINCT 与GROUP BY 基本相同,并且不会执行不必​​要的子查询。所以它也应该在这方面取胜。

      【讨论】:

      • 这对我来说看起来很有希望......但在我的实际表格测试中,它给出的结果为零? ... SELECT Entity_id FROM field_plant_descriptors WHERE (field_plant_descriptors_plant_part_ describe, field_plant_descriptors_description_term) IN ((8770, 8060), (8758, 8109), (8773, 8236)) GROUP BY Entity_id HAVING count(Entity_id) = 3
      • 从头开始......只是一个错字。谢谢!我可能会和这个一起去。我喜欢没有子查询
      • 顺便问一下,有没有办法让计数自动匹配 IN 部分中的集合数?我以前见过类似的东西,但不是为了这个。现在正在搜索该语法
      • @turpentyne。 . .一种方法是使用join 实现这样的逻辑。
      【解决方案3】:

      另一种获取具有所有这些属性的水果的方法可以使用聚合

      SELECT FRUIT
      FROM table1
      GROUP BY FRUIT
      HAVING SUM(CASE WHEN TRAIT = 'color' AND DESCRIBED = 'red' THEN 1 ELSE 0 END  ) > 0
      AND SUM(CASE WHEN TRAIT = 'shape' AND DESCRIBED = 'round' THEN 1 ELSE 0 END  ) > 0
      AND SUM(CASE WHEN TRAIT = 'surface' AND DESCRIBED = 'smooth' THEN 1 ELSE 0 END  ) > 0
      

      Demo

      使用 Mysql,您也可以使用 sum(a=b)、SUM(TRAIT = 'color' AND DESCRIBED = 'red' ) 作为简写,在 sum() 中使用表达式将得到布尔值 0/1、true/false

      【讨论】:

      • dbmitch 的解决方案对我有用,但上述方法是否有一些好处可能使其成为更好的方法?
      • @user3385160 你可以看到它使用不涉及子查询的单个查询完成所有逻辑,我也不确定你可以为两个查询运行解释计划并决定的性能
      猜你喜欢
      • 2015-10-03
      • 1970-01-01
      • 2014-02-19
      • 2021-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-26
      • 1970-01-01
      相关资源
      最近更新 更多