在MySQL中设置交集:一种干净的方式

时间:2011-12-29 06:01:36

标签: mysql sql

我想获取满足所有n个约束的实体我给它们。

ORION可以由UNION执行。如果MySQL支持INTERSECT,我不会问这个问题。

subject 中的实体及* subject_attribute *中的属性。

我认为AND操作的唯一方法是嵌套查询

SELECT id
FROM subject_attribute
WHERE attribute = 'des_sen'
AND numerical_value >= 2.0
AND id
IN (
   SELECT id
   FROM subject_attribute
   WHERE attribute = 'tough'
   AND numerical_value >= 3.5
)

这意味着:“获取满足最低子查询的实体,然后消除那些满足更高查询的实体”等等。


rows(condn x) AND rows(condn y) AND rows(cond z) <--ideal
rows(condn x:rows(cond y:rows(cond z))) <-- I am stuck here

我更喜欢线性链接条件,而不是按照我想要的方式嵌套它们

  1. 以编程方式撰写查询
  2. 更好地调试它们

  3. 我的问题:鉴于 n个人查询,我如何在MySQL中干净利落地线性化它们?

    不使用嵌套查询或存储过程。

    请注意有关个别查询的部分。


    更新:Jonathan Leffler回答说得对。 Mark Ba​​nnister的答案要简单得多(但我做出了一些糟糕的决定)。如果你仍然对连接感到困惑,请参考我的答案。

3 个答案:

答案 0 :(得分:2)

假设每个单独的查询针对同一个表运行,并且每个查询都访问attribute的不同值,则所有此类查询的最简单交叉方式如下:

SELECT id
FROM subject_attribute
WHERE (attribute = 'des_sen' AND numerical_value >= 2.0) or
      (attribute = 'tough'   AND numerical_value >= 3.5) or
...
group by id
having count(distinct attribute) = N;

- 其中N是attribute-numerical_value条件对的数量。

答案 1 :(得分:1)

不是INNER JOIN(或简称JOIN)你需要的交叉点?假设您通过相关的公共列进行连接。

因此:

SELECT s1.id
  FROM (SELECT id
          FROM subject_attribute
         WHERE attribute = 'des_sen'
           AND numerical_value >= 2.0
       ) AS s1
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'tough'
          AND numerical_value >= 3.5
       ) AS s2
    ON s1.id = s2.id

这完全延伸到N个查询(N> 2)干净且线性。


  

请解释一下如何扩展它。

SELECT s1.id
  FROM (SELECT id
          FROM subject_attribute
         WHERE attribute = 'des_sen'
           AND numerical_value >= 2.0
       ) AS s1
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'tough'
          AND numerical_value >= 3.5
       ) AS s2
    ON s1.id = s2.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'though'
          AND numerical_value = 14
       ) AS s3
    ON s1.id = s3.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'through'
          AND numerical_value != 45
       ) AS s4
    ON s1.id = s4.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'plough'
          AND numerical_value < 9
       ) AS s5
    ON s1.id = s5.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'cough'
          AND numerical_value < 5
       ) AS s6
    ON s1.id = s6.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'bucolic'
          AND numerical_value >= 3.5
       ) AS s7
    ON s1.id = s7.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'set'
          AND numerical_value BETWEEN 0.23 AND 3.0
       ) AS s8
    ON s1.id = s8.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'intelligent'
          AND numerical_value >= 0.001
       ) AS s9
    ON s1.id = s9.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'anal-retentive'
          AND numerical_value < 7
       ) AS s10
    ON s1.id = s10.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'magnificent'
          AND numerical_value = 35
       ) AS s11
    ON s1.id = s11.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'quantum'
          AND numerical_value >= 55
       ) AS s12
    ON s1.id = s12.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'thoughtfulness'
          AND numerical_value >= 350.237
       ) AS s13
    ON s1.id = s13.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'calamity'
          AND numerical_value = 3.0
       ) AS s14
    ON s1.id = s14.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'pink'
          AND numerical_value > 0.5
       ) AS s15
    ON s1.id = s15.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'cornucopia'
          AND numerical_value BETWEEN 1 AND 12
       ) AS s16
    ON s1.id = s16.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'maudlin'
          AND numerical_value < 3.625
       ) AS s17
    ON s1.id = s17.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'triad'
          AND numerical_value >= 1.723
       ) AS s18
    ON s1.id = s18.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'ambient'
          AND numerical_value >= 3.1
       ) AS s19
    ON s1.id = s19.id

答案 2 :(得分:0)

如果有人对如何连接多个查询感到困惑,这里有一个简化的表示:

SELECT result1.id
FROM (
<query #1>
) AS result1

INNER JOIN (
<query #2>
) AS result2
ON result1.id = result2.id

INNER JOIN (
<query #3>
) AS result3
ON result1.id = result3.id

其中&lt;查询#1&gt;会是

SELECT id
FROM subject_attribute
WHERE attribute = 'des_sen'
AND numerical_value >= 2.0

它被称为自联接,将表连接到自身。这里result1,result2和result3是同一个表的别名。