我有两张表如下:
CREATE List (
id INTEGER,
type INTEGER REFERENCES Types(id),
data TEXT,
PRIMARY_KEY(id, type)
);
CREATE Types (
id INTEGER PRIMARY KEY,
name TEXT
);
现在我想创建一个查询,确定已赋予类型字符串的List
的所有ID。
例如,
List: 1 0 "Some text" 1 1 "Moar text" 2 0 "Foo" 3 1 "Bar" 3 2 "BarBaz" 4 0 "Baz" 4 1 "FooBar" 4 2 "FooBarBaz" Types: 0 "Key1" 1 "Key2" 2 "Key3"
如果输入“Key1”,“Key2”,则查询应返回1,4。
如果输入“Key2”,“Key3”,则查询应返回3,4。
给定输入“Key2”,查询应返回1,3,4。
谢谢!
答案 0 :(得分:5)
select distinct l.id
from list l
inner join types t on t.id = l.type
where t.name in ('key1', 'key2')
group by l.id
having count(distinct t.id) = 2
您必须将having子句调整为您在where子句中放置的键数。只有一个键的示例:
select distinct l.id
from list l
inner join types t on t.id = l.type
where t.name in ('key2')
group by l.id
having count(distinct t.id) = 1
答案 1 :(得分:2)
您可以使用以下技巧来扩展Jurgen的想法:
with keys as (
select distinct t.id
from types t
where t.name in ('key1', 'key2')
)
select l.id
from list l join
keys k
on l.type = keys.id cross join
(select count(*) as keycnt from keys) k
group by l.id
having count(t.id) = max(k.keycnt)
即,计算子查询中的匹配键,然后将其用于计数。这样,您只需更改一行即可输入键值,并且您可以拥有任意数量的键。 (就像一个注释,我没有测试过这个SQL,所以我为任何语法错误道歉。)
答案 2 :(得分:1)
如果你可以动态生成SQL,这可能是许多DBMS中最有效的方法之一:
SELECT l.id
FROM List l
JOIN Types t1 ON t1.id = l.type
JOIN Types t2 ON t2.id = l.type
WHERE t1.name = 'Key1'
AND t2.name = 'Key2' ;
看到这个类似的问题,有超过10种获得相同结果的方法,加上一些基准(对于Postgres): How to filter SQL results in a has-many-through relation