Sql通过分组多列来选择
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sql通过分组多列来选择相关的知识,希望对你有一定的参考价值。
我有一个记录表,其中包含创建的行的日期。 (oracle db)
ID City CreateDate
1 city-1 12.12.2017
1 city-2 13.12.2017
1 city-1 13.12.2017
1 city-3 12.12.2017
....
....
我可以在一个月内创建每日报告(from this post)。例如,12月份的City-1报告。
SELECT EXTRACT(day FROM CreateDate) "Day",
COUNT(CreateDate) "Number of Reports"
FROM yourTableName
WHERE
EXTRACT(MONTH FROM CreateDate) = 12 AND
EXTRACT(YEAR FROM CreateDate) = 2017
GROUP BY EXTRACT(day FROM CreateDate)
但是我需要像这样选择和分组多个列。
Day City-1 City-2 City-3
1 10 5
2 80 60
3 60 42
4 10 37
... ... ...
30 11 12
可以sql查询产生结果吗?
答案
只需使用条件聚合:
SELECT EXTRACT(day FROM CreateDate) as Day,
SUM(CASE WHEN City = 'City-1' THEN 1 ELSE 0 END) as cnt_city1,
SUM(CASE WHEN City = 'City-2' THEN 1 ELSE 0 END) as cnt_city2,
SUM(CASE WHEN City = 'City-3' THEN 1 ELSE 0 END) as cnt_city3
FROM yourTableName
WHERE CreateDate >= DATE '2017-12-01' AND CreateDate < DATE '2018-01-01'
GROUP BY EXTRACT(day FROM CreateDate)
ORDER BY EXTRACT(day FROM CreateDate);
笔记:
- 我更改了
WHERE
条件以直接比较日期。使用EXTRACT()
使Oracle更难以使用索引。 - 我添加了一个
ORDER BY
,所以结果保证是按天订单。 - 我更改了列的名称,因此不需要进行转义。
另一答案
您可以通过旋转获得所需的结果,如下所示:
WITH t AS
(
SELECT EXTRACT(day FROM CreateDate) Day,
city
FROM yourTableName
WHERE
EXTRACT(MONTH FROM CreateDate) = '12' AND
EXTRACT(YEAR FROM CreateDate) = '2017'
GROUP BY EXTRACT(day FROM CreateDate), city
)
select * from t
PIVOT
(
count(*)
for (city) in ('city-1' as city1, 'city-2' as city2, 'city-3' as city3 )
)
ORDER BY DAY;
顺便说一句,我建议您使用绑定变量如下:
WITH t AS
(
SELECT EXTRACT(day FROM CreateDate) Day,
city
FROM yourTableName
WHERE EXTRACT(MONTH FROM CreateDate) = '&i_month' -- 12
AND EXTRACT(YEAR FROM CreateDate) = '&i_year' -- 2017
GROUP BY EXTRACT(day FROM CreateDate), city
)
select * from t
PIVOT
(
count(*)
for (city) in ('city-1' as city1, 'city-2' as city2, 'city-3' as city3 )
)
ORDER BY DAY;
这使查询参数化使用绑定变量而不是文字。通过这种方式,您的sql不需要在每次调用中进行解析,并且等待时间会减少。
以上是关于Sql通过分组多列来选择的主要内容,如果未能解决你的问题,请参考以下文章