Ste*_*eve 6 sql firebird firebird2.1
我正在使用Firebird 2.1.
这里有张桌子: IDs, Labels
同一ID可以有多个标签:
10 Peach
10 Pear
10 Apple
11 Apple
12 Pear
13 Peach
13 Apple
Run Code Online (Sandbox Code Playgroud)
假设我有一组标签,即:( Apple,Pear,Peach).
如何编写单个选择以返回在给定集合中包含所有标签的所有ID?我最好在用逗号分隔的字符串中指定集合,例如:('Apple','Pear','Peach') - >这应该返回ID = 10.
谢谢!
按照要求,我发布了 piclrow 答案的简单版本。我已经在我的 Firebird(版本 2.5)上测试了这个,但是 OP(史蒂夫)已经在 2.1 上测试过它并且它也可以工作。
SELECT id
FROM table
WHERE label IN ('Apple', 'Pear', 'Peach')
GROUP BY id
HAVING COUNT(DISTINCT label)=3
Run Code Online (Sandbox Code Playgroud)
此解决方案与 pilcrow 的缺点相同...您需要知道要查找多少个值,因为 HAVING = 条件必须与 WHERE IN 条件匹配。在这方面,Ed 的答案更加灵活,因为它拆分了连接的值字符串参数并对值进行计数。所以你只需要改变一个参数,而不是我和pilcrow使用的2个条件。
OTOH,如果关注效率,我宁愿认为(但我绝对不确定)Ed 的 CTE 方法可能比我建议的方法更难被 Firebird 引擎优化。Firebird 非常擅长优化查询,但我现在不知道当您以这种方式使用 CTE 时它是否能够做到这一点。但是 WHERE + GROUP BY + HAVING 应该可以通过简单地在 (id,label) 上建立索引来优化。
总之,如果您的案例关心执行时间,那么您可能需要一些解释计划来了解发生了什么,无论您选择哪种解决方案;)