【问题标题】:How to create a subset query in sql?如何在sql中创建子集查询?
【发布时间】:2012-08-05 04:31:45
【问题描述】:

我有两张表如下:

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,这些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。

谢谢!

【问题讨论】:

  • 您是否正在寻找可以在(几乎)所有 DBMS 或特定 DBMS 中工作的 SQL?
  • @ypercube 我正在寻找一个通用的解决方案,抱歉没有指定

标签: sql


【解决方案1】:
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

您必须根据要放入 where 子句的键数来调整 have 子句。仅一键示例:

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

SQlFiddle example

【讨论】:

  • 请参阅我回答中的最后一句话。
  • @jurgen:为什么是>= 而不是=
  • @ypercube:第二个想法是使用distinct count 和 where 子句——不需要>=
  • 您甚至不必使用DISTINCT t.id,因为PRIMARY_KEY(id, type)
【解决方案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,所以对于任何语法错误,我深表歉意。)

【讨论】:

  • +1 的努力,但我不认为 sqlite 支持这种类型的语法
  • @chacham15:你的问题没有提到 SQLite。并且 CTE(with 部分)可以轻松移动到子查询中(但您必须编写两次密钥列表)
  • @ypercube 你是对的,我没有提到它,因为我想要一个跨 SQL 兼容的解决方案。但我认识到了解决方案,所以给了它+1
【解决方案3】:

如果您可以动态生成 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

【讨论】:

  • +1 这行得通,但比其他答案效率低且更难构建
  • 实际上,它通常会比GROUP BY 的解决方案更有效。但是,是的,更难构建。这不是通用查询。
  • @chacham15:也许你可以用 SQLite 做一些性能测试,然后告诉我们结果。
  • 我真的很想尝试看看。唯一的问题是我还没有一个示例数据库来测试它:(。感谢那个链接,看到这些结果很有趣,当我最终填满数据库时,我一定会记住它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多