我想知道实现这个问题最有效的SQL查询:
假设我们有一个包含两列的表,一列存储条目ID(entry_id
),另一列存储类别ID(cat_id
):
entry_id cat_id
3 1
3 2
3 3
3 20
4 1
4 2
4 21
我想数一下类别1、2或3中有多少不同的entry_id
,但这也必须在cat_id
20中。
例如,类别1、2和3可能代表音乐流派(乡村、流行等),而类别20可能是录音格式(CD、乙烯基等)。因此,另一种口头表达方式可能是:"乙烯基和流行或乡村类别中有多少产品?"
我可以通过代码中的嵌套循环(PHP)或可能通过嵌套的SQL子查询来实现这一点,但两者都没有那么有效。我觉得这个问题一定有一个显而易见的答案。。。
编辑以添加:
我也想在不修改数据库设计的情况下这样做,因为这是一个第三方系统。
需要说明的进一步示例:
另一个真实世界中我为什么需要这些数据的例子:
比方说,类别ID代表的是:
- 住宿类型(露营=20,度假小屋=21)
或
- 大陆及其子区域(即欧洲=1,英国=2,英格兰=3)
假设有人选择了他们对露营感兴趣(cat_id
=1)。现在我们需要统计一下欧洲有多少露营产品。一个产品可能被标记为欧洲(父母)、英国(子女)和英国(孙子女),给我们一系列类别id 1、2或3。因此,我们现在需要统计这两个类别和最初的住宿类别1(露营)中有多少不同的产品。
因此,选择Camping后,最终结果可能看起来像:
- 欧洲:4款露营产品
- 英国:2种露营产品
- 英格兰:1款露营产品
- 威尔士:1个露营产品
- 法国:2款露营产品等等
- 英国:2种露营产品
希望能有所帮助。。。
我相信您想要GROUP BY、COUNT()和EXISTS()
declare @t table(entry_id int, cat_id int)
insert @t select 1, 1
insert @t select 2, 1
insert @t select 1, 2
insert @t select 2, 2
insert @t select 3, 1
insert @t select 1, 20
select t1.cat_id, COUNT(*)
from @t as t1
where exists(
select * from @t
where t1.entry_id = entry_id
and cat_id = 20)
group by t1.cat_id
V2使用join而不是EXISTS()
declare @t table(entry_id int, cat_id int)
insert @t select 1, 1
insert @t select 2, 1
insert @t select 1, 2
insert @t select 2, 2
insert @t select 3, 1
insert @t select 1, 20
select t1.cat_id, COUNT(*)
from @t as t1
join @t as t2 on t1.entry_id = t2.entry_id and t2.cat_id = 20
group by t1.cat_id
select count(distinct entry_id) from myTable where cat_id=20 and entry_id in
(select distinct entry_id from myTable where cat_id in (1,2,3));
没有子查询,使用JOIN
和GROUP BY
:
使用entry_id将表连接到表本身(这为该entry_id提供了所有可能的cat_id对)。选择cat_id既是(1,2,3)的成员又是第二个cat_id=20的行。
SELECT r1.entry_id
FROM records r1
JOIN records r2 USING(entry_id)
WHERE r1.cat_id IN (1,2,3)
AND r2.cat_id = 20 GROUP BY entry_id;