我有几张桌子组成了现场/工作室音乐的媒体目录,其中每个媒体项目都有零个显示日期,CD和与之相关的乙烯基。我现在的查询提取的统计信息会导致所有可用媒体项的表格数据集。我现在无法扩展查询以在每个关联的表中包含更精细的统计信息。
架构:
media(id , title)
cd(media_fk, type)
vinyl(media_fk)
gig(id, date)
media_gigs(gig_fk, media_fk)
我到目前为止的查询:
SELECT m.id, m.title, COUNT(DISTINCT c.id) as cds, COUNT(DISTINCT v.id) as vinyl, gig.id as gid, gig.date as gdate
FROM media m
LEFT JOIN cd c on m.id = c.media
LEFT JOIN vinyl v on m.id = v.media
LEFT JOIN media_gigs g on m.id = g.media
LEFT JOIN gig gig on g.gig = gig.id
GROUP BY m.id, gig.id;
产生:
id | title | cds | vinyl | gid | gdate
---+---------+-----+-------+--------------------------+------------
1 | title 1 | 5 | 1 | may-11-1989-kawasaki | 1989-05-11
1 | title 1 | 5 | 1 | may-13-1989-tokyo | 1989-05-13
2 | title 2 | 6 | 0 | apr-29-1998-nagoya | 1998-04-29
2 | title 2 | 6 | 0 | may-6-1998-tokyo | 1998-05-06
2 | title 2 | 6 | 0 | may-7-1998-tokyo | 1998-05-07
3 | title 3 | 6 | 2 | dec-1-1986-new-york-city | 1986-12-01
3 | title 3 | 6 | 2 | dec-5-1986-quebec-city | 1986-12-05
3 | title 3 | 6 | 2 | nov-19-1986-tokyo | 1986-11-19
3 | title 3 | 6 | 2 | nov-20-1986-tokyo | 1986-11-20
cd.type
是[silver,cdr,pro-cdr]
的枚举类型,我想要添加到结果中。因此,最终目标是增加3个附加列,这些列是与每个媒体项相关联的cd类型的计数。我没有使用COUNT
找到正确的语法,或者根据其类型聚合cd
,因此正在寻找正确方向的推送。我对SQL很新,所以到目前为止我可能有点天真。
使用PG 9.3。
答案 0 :(得分:2)
您可以使用CASE函数确定cd类型并根据结果执行SUM,如下所示:
SELECT
m.id,
m.title,
COUNT(DISTINCT c.id) as cds,
COUNT(DISTINCT v.id) as vinyl,
gig.id as gid, gig.date as gdate,
SUM(case cd.type
when 'silver' then 1
else 0
end) silver,
SUM(case cd.type
when 'cdr' then 1
else 0
end) cdr,
SUM(case cd.type
when 'pro-cdr' then 1
else 0
end) pro_cdr
FROM media m
LEFT JOIN cd c on m.id = c.media
LEFT JOIN vinyl v on m.id = v.media
LEFT JOIN media_gigs g on m.id = g.media
LEFT JOIN gig gig on g.gig = gig.id
GROUP BY m.id, gig.id;
<强>参考强>:
答案 1 :(得分:0)
正如其他海报所提到的,您可以在c.type列上使用SUM(CASE WHEN <cond1> THEN 1 ELSE 0)
构造执行此操作。
我想提及您的SQL还有其他一些问题:
错误使用LEFT JOIN
您可以将值分组为NULL:gig.id.这可能是因为LEFT JOIN的使用不正确。如果要在结果集中保留连接表中没有匹配项的行,则仅使用左连接。
所以在CD表上左连接是正确的,因为你也希望能够显示有0个CD。在media_gigs和gigs表上你可能想要一个INNER JOIN,因为总是必须匹配。
编辑:我错误地认为这是不正确的。我从样本数据中假设您不想显示没有演出的媒体。
非分组,非汇总列
在查询中,选择未分组的列,这些列不是聚合函数(如SUM,COUNT)。虽然一些Db方言可能接受这一点,但这是不好的做法。例如,请执行以下查询:
SELECT x, y, SUM(z) FROM t
GROUP BY x;
如果y在功能上不依赖于x,也就是说,如果x的一个值可以有不同的y值,则不清楚应该显示这些值中的哪一个。因此,您应该像这样写:
SELECT x, y, SUM(z) FROM t
GROUP BY x, y;