2017-04-10 50 views
0

我有以下的MYSQL查詢,試圖選擇存在於查詢#1但不存在於查詢#2中的行,我嘗試使用NOT EXISTS,但該概念不適用於我的用例,我提供了樣本數據和結果,有沒有其他方法可以用於我的用例?我在尋找什麼?如何在第一個查詢中選擇行但在第二個查詢中不存在?

SELECT 
    si.software_image_id, 
    si.software_image, 
    sib.software_image_build, 
    si.software_image_tag_id 
FROM software_product_builds spb 
INNER JOIN software_product_build_software_image_builds spbsib ON spb.software_product_build_id = spbsib.software_product_build_id 
INNER JOIN software_image_builds sib ON spbsib.software_image_build_id = sib.software_image_build_id 
INNER JOIN software_images si ON sib.software_image_id = si.software_image_id 
WHERE spb.software_product_build = 'CI_xxxx.LA.0.1-03291-STD.INT-7' and NOT EXISTS 

(SELECT 
    si.software_image_id, 
    si.software_image, 
    sib.software_image_build, 
    si.software_image_tag_id 
FROM software_product_builds spb 
INNER JOIN software_product_build_software_image_builds spbsib ON spb.software_product_build_id = spbsib.software_product_build_id 
INNER JOIN software_image_builds sib ON spbsib.software_image_build_id = sib.software_image_build_id 
INNER JOIN software_images si ON sib.software_image_id = si.software_image_id 
WHERE spb.software_product_build = 'CI_xxxx.LA.0.1-03291-STD.INT-6') 

查詢#1結果

query1

查詢#2結果

query2

預期的輸出: -

1781 BTFM.HW_NPR.1.1 BTFM.HW_NPR.1.1-00007-QCACHROM-1 2 
+0

我可能正在太快看這個,但預期的輸出結果確實出現在兩個查詢中都正確嗎?所以爲了得到你期望的輸出結果,你想在兩個查詢中都說'EXIST'? –

+0

@JasonJoslin - 不,它只出現在查詢#1中,注意最後幾位BTFM.HW_NPR.1.1-'00007',它是查詢#2中的BTFM.HW_NPR.1.1-'00006' – user3508811

+0

中的子查詢存在不是相關的,因此當mysql通過外部查詢的結果循環時,結果不會改變。您需要使用子查詢的where子句將外部查詢與子查詢連接起來。 Sonce再次沒有詳細描述問題,很難提出解決方案。您可能需要檢查全部4個字段。 – Shadow

回答

0

LEFT JOIN方法 - 慢

我從來沒有使用不存在方法之前,但也許如果你離開加入第二個查詢你的第一個查詢,得到的結果它僅出現在第一個查詢應該工作。我覺得是這樣的:

SELECT 
    query_1.* 
FROM 
    (SELECT 
     si.software_image_id, 
      si.software_image, 
      sib.software_image_build, 
      si.software_image_tag_id 
    FROM 
     software_product_builds spb 
    INNER JOIN software_product_build_software_image_builds spbsib ON spb.software_product_build_id = spbsib.software_product_build_id 
    INNER JOIN software_image_builds sib ON spbsib.software_image_build_id = sib.software_image_build_id 
    INNER JOIN software_images si ON sib.software_image_id = si.software_image_id 
    WHERE 
     spb.software_product_build = 'CI_xxxx.LA.0.1-03291-STD.INT-7') AS query_1 
     LEFT JOIN 
    (SELECT 
     si.software_image_id, 
      si.software_image, 
      sib.software_image_build, 
      si.software_image_tag_id 
    FROM 
     software_product_builds spb 
    INNER JOIN software_product_build_software_image_builds spbsib ON spb.software_product_build_id = spbsib.software_product_build_id 
    INNER JOIN software_image_builds sib ON spbsib.software_image_build_id = sib.software_image_build_id 
    INNER JOIN software_images si ON sib.software_image_id = si.software_image_id 
    WHERE 
     spb.software_product_build = 'CI_xxxx.LA.0.1-03291-STD.INT-6') AS query_2 ON query_1.software_image_build = query_2.software_image_build 
WHERE 
    query_2.software_image_build IS NULL 

假設software_product_build是要測試對

NOT IN的方法獨特的領域 - 慢

如果不加入不好的表現,你可以做一個簡單的字段是不是在第二個查詢如:

SELECT 
    si.software_image_id, 
    si.software_image, 
    sib.software_image_build, 
    si.software_image_tag_id 
FROM 
    software_product_builds spb 
     INNER JOIN 
    software_product_build_software_image_builds spbsib ON spb.software_product_build_id = spbsib.software_product_build_id 
     INNER JOIN 
    software_image_builds sib ON spbsib.software_image_build_id = sib.software_image_build_id 
     INNER JOIN 
    software_images si ON sib.software_image_id = si.software_image_id 
WHERE 
    spb.software_product_build = 'CI_xxxx.LA.0.1-03291-STD.INT-7' 
     AND sib.software_image_build NOT IN (SELECT 
      sib.software_image_build 
     FROM 
      software_product_builds spb 
       INNER JOIN 
      software_product_build_software_image_builds spbsib ON spb.software_product_build_id = spbsib.software_product_build_id 
       INNER JOIN 
      software_image_builds sib ON spbsib.software_image_build_id = sib.software_image_build_id 
       INNER JOIN 
      software_images si ON sib.software_image_id = si.software_image_id 
     WHERE 
      spb.software_product_build = 'CI_xxxx.LA.0.1-03291-STD.INT-6') 

無論哪種方式,你仍然需要d確定你的唯一標識符是什麼,這樣你可以檢查它不存在於第二個查詢中(就像@shadow指出的那樣)。 SQL如何知道匹配檢查不存在? SQL需要確切地知道它匹配的是什麼。即使您需要通過連接他們像檢查字段的組合:

WHERE CONCAT(si.software_image, sib.software_image_build,) NOT IN (SELECT CONCAT(si.software_image,sib.software_image_build) FROM ......., 

最後更新,NOT EXISTS方法 - 最佳性能

上陰影的後面評論我已經找到NOT EXISTS方法性能要好得多。因此,請嘗試:

SELECT 
    si.software_image_id, 
    si.software_image, 
    sib.software_image_build, 
    si.software_image_tag_id 
FROM 
    software_product_builds spb 
     INNER JOIN 
    software_product_build_software_image_builds spbsib ON spb.software_product_build_id = spbsib.software_product_build_id 
     INNER JOIN 
    software_image_builds sib ON spbsib.software_image_build_id = sib.software_image_build_id 
     INNER JOIN 
    software_images si ON sib.software_image_id = si.software_image_id 
WHERE 
    spb.software_product_build = 'CI_xxxx.LA.0.1-03291-STD.INT-7' 
     AND NOT EXISTS(SELECT 
      * 
     FROM 
      software_product_builds spb_two 
       INNER JOIN 
      software_product_build_software_image_builds spbsib_two ON spb_two.software_product_build_id = spbsib_two.software_product_build_id 
       INNER JOIN 
      software_image_builds sib_two ON spbsib_two.software_image_build_id = sib_two.software_image_build_id 
       INNER JOIN 
      software_images si_two ON sib_two.software_image_id = si_two.software_image_id 
     WHERE 
      spb_two.software_product_build = 'CI_xxxx.LA.0.1-03291-STD.INT-6' 
       AND sib_two.software_image_id = sib.software_image_id) 
+0

如何將2個查詢聯繫起來,我也不明白。順便說一句,對於這種類型的問題,不存在的子查詢的性能通常比左連接更好,因爲不存在不必從右側的表達式獲取任何數據,而連接則可以。 – Shadow

+0

他們是不相關的,他們是兩個單獨的查詢..問題是如何打印只查詢#1中不存在的查詢#2中的行,如果不存在不起作用,是否有任何替代? – user3508811

+0

@ user3508811如果2個查詢與其他每個查詢都不相關,那麼你的問題根本就沒有任何意義。您必須定義何時考慮子查詢中存在的外部查詢中的記錄。那將是你們的關係。 – Shadow

相關問題