如何在第一个查询中选择行但在第二个查询中不存在?

时间:2017-04-10 23:44:01

标签: mysql database

我有以下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

1 个答案:

答案 0 :(得分:0)

LEFT JOIN METHOD - SLOW

我以前从未使用过not exists方法,但是如果您将第二个查询加入到第一个查询中并获得只出现在第一个查询中的结果应该可行。我想是这样的:

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 METHOD - SLOW

如果左连接对性能有害,你可以做一个简单的where字段不在第二个查询中:

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')

无论哪种方式,您仍然需要确定您的唯一标识符是什么,以便您可以检查它在第二个查询中是否不存在(如@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方法在性能方面要好得多。所以试试:

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)