2011-12-29 62 views
1

我想獲取滿足所有n約束的實體我給他們。在MySQL中設置交叉點:一個乾淨的方式

或操作可以由UNION執行。如果MySQL支持INTERSECT,我不會問這個問題。

我有表主題中的實體及其在* subject_attribute *中的屬性。

我看到的唯一方法操作爲嵌套查詢

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. 調試他們更好地

我的問題:鑑於個人查詢,我如何與他們在MySQL乾淨和線性?

不通過使用嵌套查詢或存儲過程。

請注意關於個人查詢的部分。


更新:喬納森·萊弗勒回答是正確的。馬克班尼斯特的答案非常簡單(但我做出了一些糟糕的決定)。如果您仍然對加入感到困惑,請參閱我的回答。

+0

請問你可以在查詢中包含表結構嗎? – 2011-12-29 10:09:36

回答

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-numeric_value條件對的數量。

1

是不是一個INNER 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 
+0

請解釋你如何擴展它 – aitchnyu 2011-12-29 08:36:23

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 

其中<查詢#1>將是

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

它被稱爲自連接,將自己連接到一個表。這裏result1,result2和result3是同一個表的別名。

+0

只有當每個結果行的唯一鍵保存在同一個字段'id'中時才爲真。 – 2011-12-29 10:12:01

+0

Mark Ba​​nnister,請詳細說明 – aitchnyu 2011-12-29 10:16:17

+0

Aitchnyu,請詳細說明您的''查詢。 – 2011-12-29 10:21:19