Select 个来自两个表的元素,其中 JOIN 和 UNION 不包括列中的 ID
Select elements from two tables with JOIN and UNION excluding IDs in a column
我有 3 个这样的 SQL 表:
tbl_items
id ... name ... value ... active
1 color red 1
2 style modern 1
3 age old 1
4 size small 1
tbl_adv_items
id ... name ... value ... active
1 texture suave 0
2 material plastic 1
tbl_items_classes
id ... item_id
1 1
2 3
我想 select 来自 tbl_items
和 tbl_adv_items
的所有 ID,条件是:如果项目的 ID 存在于 item_id
中,则从 tbl_items
中排除项目来自 tbl_items_classes
的专栏
现在我有这个查询:
SELECT tbl_items.id FROM tbl_items
JOIN tbl_items_classes ON tbl_items_classes.item_id <> tbl_items.id
WHERE tbl_items.active = 1
UNION ALL SELECT id FROM tbl_adv_items WHERE active = 1
这给了我所有的项目,包括那些 ID 在 item_id
中的项目。不应返回来自 tbl_items
的 ID 1 和 3。我想我需要一个 JOIN
这里但我不能让它工作
使用EXCEPT
:
SELECT id FROM tbl_items WHERE tbl_items.active = 1
UNION ALL
SELECT id FROM tbl_adv_items WHERE active = 1
EXCEPT
SELECT item_id FROM tbl_items_classes
这将产生排除 table tbl_items_classes
.
中包含的所有 item_id
值的效果
编辑:
如果您还想知道查询返回的 id
的来源(OP 中未明确说明的内容),则可以使用以下查询:
(SELECT id, 0 AS origin_table FROM tbl_items WHERE tbl_items.active = 1
UNION ALL
SELECT id, 1 AS origin_table FROM tbl_adv_items WHERE active = 1)
EXCEPT
(SELECT item_id, 0 AS origin_table FROM tbl_items_classes
UNION ALL
SELECT item_id, 1 AS origin_table FROM tbl_items_classes)
出于性能原因使用经典 LEFT JOIN
:
WITH cte AS (
SELECT id , 'tbl_items' AS origin
FROM tbl_items
WHERE active = 1
UNION ALL
SELECT id, 'tbl_adv_items' AS origin
FROM tbl_adv_items
WHERE active = 1
)
SELECT c.id, c.origin
FROM cte c
LEFT JOIN tbl_items_classes cl
ON c.id = cl.item_id
WHERE cl.item_id IS NULL;
剩下第二个case。
资料来源:http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins
您可以简单地在表之间进行连接并放置一个条件来过滤记录。试试这个:
select * from tbl_items tblA
inner join tbl_adv_items tblB on tblA.id = tblB.Id
left outer join tbl_items_classes tblC on tblA.id = tblC.item_Id
where tblC.Id is null -- this check will exclude desired items
我有 3 个这样的 SQL 表:
tbl_items
id ... name ... value ... active
1 color red 1
2 style modern 1
3 age old 1
4 size small 1
tbl_adv_items
id ... name ... value ... active
1 texture suave 0
2 material plastic 1
tbl_items_classes
id ... item_id
1 1
2 3
我想 select 来自 tbl_items
和 tbl_adv_items
的所有 ID,条件是:如果项目的 ID 存在于 item_id
中,则从 tbl_items
中排除项目来自 tbl_items_classes
现在我有这个查询:
SELECT tbl_items.id FROM tbl_items
JOIN tbl_items_classes ON tbl_items_classes.item_id <> tbl_items.id
WHERE tbl_items.active = 1
UNION ALL SELECT id FROM tbl_adv_items WHERE active = 1
这给了我所有的项目,包括那些 ID 在 item_id
中的项目。不应返回来自 tbl_items
的 ID 1 和 3。我想我需要一个 JOIN
这里但我不能让它工作
使用EXCEPT
:
SELECT id FROM tbl_items WHERE tbl_items.active = 1
UNION ALL
SELECT id FROM tbl_adv_items WHERE active = 1
EXCEPT
SELECT item_id FROM tbl_items_classes
这将产生排除 table tbl_items_classes
.
item_id
值的效果
编辑:
如果您还想知道查询返回的 id
的来源(OP 中未明确说明的内容),则可以使用以下查询:
(SELECT id, 0 AS origin_table FROM tbl_items WHERE tbl_items.active = 1
UNION ALL
SELECT id, 1 AS origin_table FROM tbl_adv_items WHERE active = 1)
EXCEPT
(SELECT item_id, 0 AS origin_table FROM tbl_items_classes
UNION ALL
SELECT item_id, 1 AS origin_table FROM tbl_items_classes)
出于性能原因使用经典 LEFT JOIN
:
WITH cte AS (
SELECT id , 'tbl_items' AS origin
FROM tbl_items
WHERE active = 1
UNION ALL
SELECT id, 'tbl_adv_items' AS origin
FROM tbl_adv_items
WHERE active = 1
)
SELECT c.id, c.origin
FROM cte c
LEFT JOIN tbl_items_classes cl
ON c.id = cl.item_id
WHERE cl.item_id IS NULL;
剩下第二个case。
您可以简单地在表之间进行连接并放置一个条件来过滤记录。试试这个:
select * from tbl_items tblA
inner join tbl_adv_items tblB on tblA.id = tblB.Id
left outer join tbl_items_classes tblC on tblA.id = tblC.item_Id
where tblC.Id is null -- this check will exclude desired items