4

我有两个表如下:

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。

例如,

列表:
1 0 "一些文字"
1 1“摩尔文本”
2 0 "富"
3 1“酒吧”
3 2“巴巴兹”
4 0 “巴兹”
4 1“FooBar”
4 2“FooBarBaz”

类型:
0“钥匙1”
1“钥匙2”
2“钥匙3”

给定输入“Key1”、“Key2”,查询应返回 1、4。

给定输入“Key2”、“Key3”,查询应返回 3、4。

给定输入“Key2”,查询应返回 1、3、4。

谢谢!

4

3 回答 3

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

SQLlFiddle 示例

于 2012-08-04T19:53:53.073 回答
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,所以对于任何语法错误,我深表歉意。)

于 2012-08-04T20:05:39.073 回答
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 relationship

于 2012-08-04T20:17:25.667 回答