Sql通过分组多列来选择

时间:2017-12-23 20:10:48

标签: sql oracle pivot

我有一个记录表,其中包含创建的行的日期。 (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月份的城市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查询可以产生结果吗?

2 个答案:

答案 0 :(得分:0)

只需使用条件聚合:

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,因此结果保证按天订单。
  • 我更改了列的名称,因此无需转义。

答案 1 :(得分:0)

您可以通过旋转获得所需的结果,如下所示:

systemctl stop firewalld
systemctl disable firewalld
systemctl status firewalld

D e m o

顺便说一句,我建议您使用绑定变量,如下所示:

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;

使查询参数化使用绑定变量而不是文字。这样就不需要在每个调用中解析你的sql了,等待时间也减少了。