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;

D e m o

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

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通过分组多列来选择的主要内容,如果未能解决你的问题,请参考以下文章

按键将记录分组到具有多列的单行中

如何在 SQL 中按多列分组并按日期排序?

SQL中的Group By的查询过程多列分组的查询过程是怎样的?

SQL 中多列“级联”约束的优雅语法?

使用右表上的总和分组对多列进行 SQL 连接

带有分组的单列表中的 MySql 多列选择