如何比较具有多个联合的表并加入?
How to compare tables with many unions and join?
我正在尝试查找仅在一个 table 中出现的行。大 table 名称(包含所有行)是 kwf_uploads
,小 table 出现在许多名称中。我的目标是找到存在于 kwf_uploads
中但不存在于其他行中的行(此示例是 table 中没有关系的主键和外键)。
我在 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
找到它:SQL: cascade UNION and JOIN
但失败并出现错误:SQL (1052): Column "id" in field list is ambiguous
。
我不想对每个 table 使用连接,因为我不擅长连接并且 sql 变得非常大且不可读。我也试过 not exists
contrustion 没有任何结果。
我想我们可以找到更好的解决方案 =)
select id from kwf_uploads
查询的结果(9690 行):
联合查询的结果(6096 行):
结果我想看到 3594(9690 减去 6096)行。
修复您当前的错误
具有正确结果集别名的前缀 ID 列。在这种情况下 kwf_uploads.id
。因为 Id 存在于两个结果集中。
得到想要的输出
添加Where foo.id is null
。这将获取那些加入失败的 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
在 DarkKnight 旁边回答:
您不需要在每个 union select
上包含 where
。最坏的情况是你从所有 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
UNION(单独使用时,没有 ALL)是一个 "expensive" 操作。
有一个替代方案,不存在。这个构造是 "semi join",我怀疑它可能比联合方法更便宜。
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 )
我正在尝试查找仅在一个 table 中出现的行。大 table 名称(包含所有行)是 kwf_uploads
,小 table 出现在许多名称中。我的目标是找到存在于 kwf_uploads
中但不存在于其他行中的行(此示例是 table 中没有关系的主键和外键)。
我在 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
找到它:SQL: cascade UNION and JOIN
但失败并出现错误:SQL (1052): Column "id" in field list is ambiguous
。
我不想对每个 table 使用连接,因为我不擅长连接并且 sql 变得非常大且不可读。我也试过 not exists
contrustion 没有任何结果。
我想我们可以找到更好的解决方案 =)
select id from kwf_uploads
查询的结果(9690 行):
联合查询的结果(6096 行):
结果我想看到 3594(9690 减去 6096)行。
修复您当前的错误
具有正确结果集别名的前缀 ID 列。在这种情况下 kwf_uploads.id
。因为 Id 存在于两个结果集中。
得到想要的输出
添加Where foo.id is null
。这将获取那些加入失败的 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
在 DarkKnight 旁边回答:
您不需要在每个 union select
上包含 where
。最坏的情况是你从所有 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
UNION(单独使用时,没有 ALL)是一个 "expensive" 操作。
有一个替代方案,不存在。这个构造是 "semi join",我怀疑它可能比联合方法更便宜。
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 )