我有两个主要表:codes
和categories
。
我还有一个联接表code_mappings
,它将代码与类别相关联。
我需要能够确定哪些代码映射到一组类别,但没有映射到另一组。一时间撞到我的脑袋,但我完全卡住了。
这是架构:
create table codes(
id int,
name varchar(256));
create table code_mappings(
id int,
code_id int,
category_id int);
create table categories(
id int,
name varchar(256));
一些种子数据:
INSERT INTO categories VALUES(1, 'Dental');
INSERT INTO categories VALUES(2, 'Weight');
INSERT INTO categories VALUES(3, 'Other');
INSERT INTO categories VALUES(4, 'Acme Co');
INSERT INTO categories VALUES(5, 'No Name');
INSERT INTO codes VALUES(100, "big bag of cat food");
INSERT INTO codes VALUES(200, "healthy doggie treatz");
INSERT INTO code_mappings VALUES(50, 200, 1);
INSERT INTO code_mappings VALUES(51, 100, 4);
INSERT INTO code_mappings VALUES(52, 100, 3);
我如何编写一个查询,它将为我提供映射到类别(1,2,3)之一而不是其中一个类别(4,5)的代码?
答案 0 :(得分:1)
这是set-within-sets
查询的示例。我喜欢使用group by
和having
来解决这些问题,因为我发现这是最灵活的方法:
select cm.code_id
from code_mappings cm
group by cm.code_id
having sum(case when cm.category_id in (1, 2, 3) then 1 else 0 end) = 1 and
sum(case when cm.category_id in (4, 5) then 1 else 0 end) = 0;
having
子句中的每个条件都实现了其中一个条件。你说一个代码是1,2或3,因此是= 1
(如果你想要这三个中的至少一个,它将是> 0
)。你说没有4或5,因此= 0
。
答案 1 :(得分:1)
SELECT *
FROM codes co
WHERE EXISTS (
SELECT *
FROM code_mappings ex
WHERE ex.code_id = co.id
AND ex.category_id IN (1,2,3)
)
AND NOT EXISTS (
SELECT *
FROM code_mappings nx
WHERE nx.code_id = co.id
AND nx.category_id IN (4,5)
)
;