简体   繁体   English

如何比较具有多个联合和联接的表?

[英]How to compare tables with many unions and join?

I'm trying to find rows which are present only in one table. 我正在尝试查找仅在一个表中存在的行。 Big table name (consists all rows) is kwf_uploads , small tables present in many names. 大表名(包括所有行)是kwf_uploads ,小表中有许多名称。 My goal is find rows which exists in kwf_uploads , but not exists in other (this example are primary and foreigh keys in tables without relations). 我的目标是查找存在于kwf_uploads行,但不存在于其他行中(此示例是没有关系的表中的主键和foreigh键)。

What I did in sql: 我在sql中做了什么:

select id from
kwf_uploads
left join

(SELECT picture_id as id
FROM documents where picture_id is not null
UNION 
SELECT file_id as id
FROM books where file_id is not null
UNION 
SELECT picture_id as id
FROM employee where picture_id is not null
UNION 
SELECT file_id as id
FROM flightFiles where file_id is not null
UNION 
SELECT picture_id as id
FROM tasks where picture_id is not null
UNION 
SELECT picture_id as id
FROM trainingContentQuestions where picture_id is not null
UNION 
SELECT picture_id as id
FROM trainingQuestions where picture_id is not null) foo  

ON kwf_uploads.id = foo.id

Find it on: SQL: cascade UNION and JOIN 在以下位置找到它: SQL:级联UNION和JOIN

But it fails with error: SQL (1052): Column "id" in field list is ambiguous . 但是它失败并显示错误: SQL (1052): Column "id" in field list is ambiguous

I don't want to use join with every table, because I'm not good in joins and sql becomes very large and unreadable. 我不想对每个表都使用join,因为我不擅长join,而sql变得非常大且难以读取。 I also tried not exists contrustion without any results. 我还尝试了not exists任何结果的委托。 I think we can find a better solution =) 我认为我们可以找到更好的解决方案=)

Result from select id from kwf_uploads query (9690 rows): select id from kwf_uploads查询的select id from kwf_uploads结果(9690行):

在此处输入图片说明

Result from union queries (6096 rows): 联合查询的结果(6096行):

在此处输入图片说明

In result I want to see 3594 (9690 minus 6096) rows. 结果,我想查看3594(9690减去6096)行。

UNION (when used by itself, without ALL) is an "expensive" operation. UNION(单独使用时不使用ALL)是一种“昂贵”的操作。

There is an alternative, NOT EXISTS. 有一个替代方法,“不存在”。 This construct is a "semi join" and I suspect may be less expensive than a union approach. 这种构造是“半联接”,我怀疑它可能比联合方法便宜。

SELECT
      id
FROM kwf_uploads AS u
WHERE NOT EXISTS     (SELECT NULL FROM documents WHERE u.id = picture_id )
      AND NOT EXISTS (SELECT NULL FROM books WHERE u.id = file_id )
      AND NOT EXISTS (SELECT NULL FROM employee WHERE u.id = picture_id )
      AND NOT EXISTS (SELECT NULL FROM flightFiles WHERE u.id = file_id )
      AND NOT EXISTS (SELECT NULL FROM tasks WHERE u.id = picture_id )
      AND NOT EXISTS (SELECT NULL FROM trainingContentQuestions WHERE u.id = picture_id )
      AND NOT EXISTS (SELECT NULL FROM trainingQuestions WHERE u.id = picture_id )

To fix your current error 解决您当前的错误

Prefix Id column with proper resultset alias. 具有正确结果集别名的前缀ID列。 In this case kwf_uploads.id . 在这种情况下, kwf_uploads.id Because Id exists in both resultsets. 因为两个结果集中都存在ID。

To get desired output 获得所需的输出

Add Where foo.id is null . 添加Where foo.id is null This will fetch those ids which failed in join, those are the ids you want. 这将获取那些加入失败的ID,即您想要的ID。

  select kwf_uploads.id from
        kwf_uploads
        left join

        (SELECT picture_id as id
        FROM documents where picture_id is not null
        UNION 
        SELECT file_id as id
        FROM books where file_id is not null
        UNION 
        SELECT picture_id as id
        FROM employee where picture_id is not null
        UNION 
        SELECT file_id as id
        FROM flightFiles where file_id is not null
        UNION 
        SELECT picture_id as id
        FROM tasks where picture_id is not null
        UNION 
        SELECT picture_id as id
        FROM trainingContentQuestions where picture_id is not null
        UNION 
        SELECT picture_id as id
        FROM trainingQuestions where picture_id is not null) foo  

        ON kwf_uploads.id = foo.id
        where foo.id is null

Beside DarkKnight answer: 在DarkKnight旁边回答:

You dont need include where on each union select . 您不需要在每个union select where Worst case you get one NULL from all the UNION but that wont appear on the LEFT JOIN anyway 最坏的情况是您从所有UNION得到一个NULL ,但是无论如何都不会出现在LEFT JOIN

select kwf_uploads.id 
from kwf_uploads
left join
    (
    SELECT picture_id as id FROM documents
    UNION 
    SELECT file_id as id FROM books
    UNION 
    SELECT picture_id as id FROM employee
    UNION 
    SELECT file_id as id FROM flightFiles
    UNION 
    SELECT picture_id as id FROM tasks
    UNION 
    SELECT picture_id as id FROM trainingContentQuestions 
    UNION 
    SELECT picture_id as id FROM trainingQuestions
    ) foo      
ON kwf_uploads.id = foo.id
where foo.id is null

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM