如何使这个SQL查询更优雅?

时间:2017-05-24 08:51:27

标签: mysql sql

这是我获取计数值的MySQL查询...

SELECT 1 AS id,
       '2016' AS Year,
       MAX( IF( Month = '01', Count, 0 ) ) AS 'VAL01',
       MAX( IF( Month = '02', Count, 0 ) ) AS 'VAL02',
       MAX( IF( Month = '03', Count, 0 ) ) AS 'VAL03',
       MAX( IF( Month = '04', Count, 0 ) ) AS 'VAL04',
       MAX( IF( Month = '05', Count, 0 ) ) AS 'VAL05',
       MAX( IF( Month = '06', Count, 0 ) ) AS 'VAL06',
       MAX( IF( Month = '07', Count, 0 ) ) AS 'VAL07',
       MAX( IF( Month = '08', Count, 0 ) ) AS 'VAL08',
       MAX( IF( Month = '09', Count, 0 ) ) AS 'VAL09',
       MAX( IF( Month = '10', Count, 0 ) ) AS 'VAL10',
       MAX( IF( Month = '11', Count, 0 ) ) AS 'VAL11',
       MAX( IF( Month = '12', Count, 0 ) ) AS 'VAL12',
       SUM( Count ) AS Total
FROM ( SELECT DATE_FORMAT( created_at, '%m' ) AS Month,
              COUNT( 1 ) AS Count
       FROM reservations
       WHERE DATE_FORMAT( created_at, '%Y' ) = '2016'
       GROUP BY DATE_FORMAT( created_at, '%m' )
     ) AS T1
UNION
SELECT 2 AS id,
       '2017' AS Year,
       MAX( IF( Month = '01', Count, 0 ) ) AS 'VAL01',
       MAX( IF( Month = '02', Count, 0 ) ) AS 'VAL02',
       MAX( IF( Month = '03', Count, 0 ) ) AS 'VAL03',
       MAX( IF( Month = '04', Count, 0 ) ) AS 'VAL04',
       MAX( IF( Month = '05', Count, 0 ) ) AS 'VAL05',
       MAX( IF( Month = '06', Count, 0 ) ) AS 'VAL06',
       MAX( IF( Month = '07', Count, 0 ) ) AS 'VAL07',
       MAX( IF( Month = '08', Count, 0 ) ) AS 'VAL08',
       MAX( IF( Month = '09', Count, 0 ) ) AS 'VAL09',
       MAX( IF( Month = '10', Count, 0 ) ) AS 'VAL10',
       MAX( IF( Month = '11', Count, 0 ) ) AS 'VAL11',
       MAX( IF( Month = '12', Count, 0 ) ) AS 'VAL12',
       SUM( Count ) AS Total
FROM ( SELECT DATE_FORMAT( created_at, '%m' ) AS Month,
              COUNT( 1 ) AS Count
       FROM reservations
       WHERE DATE_FORMAT( created_at, '%Y' ) = '2017'
       GROUP BY DATE_FORMAT( created_at, '%m' )
     ) AS T2

返回(例如)......

+----+------+-------+-------+-------+-------+-------+-------+-----+-------+-------+
| id | Year | VAL01 | VAL02 | VAL03 | VAL04 | VAL05 | VAL06 | ... | VAL12 | Total |
+----+------+-------+-------+-------+-------+-------+-------+-----+-------+-------+
|  1 | 2016 |     0 |     0 |   150 |   190 |   200 |   220 | ... |   160 |  1242 |
+----+------+-------+-------+-------+-------+-------+-------+-----+-------+-------+
|  2 | 2017 |   300 |   300 |   600 |   600 |   700 |     0 | ... |     0 |  2500 |
+----+------+-------+-------+-------+-------+-------+-------+-----+-------+-------+

我的查询有很多问题。它无法使用年份2018,并且应该一次又一次地使用UNION

如何让我的SQL查询更美观?

4 个答案:

答案 0 :(得分:1)

试试这个

select 
date_format(created_at,'%Y') as Year,
sum(case when date_format(created_at,'%m')='01' then 1 else 0 end) as val01,
sum(case when date_format(created_at,'%m')='02' then 1 else 0 end) as val02,
sum(case when date_format(created_at,'%m')='03' then 1 else 0 end) as val03,
sum(case when date_format(created_at,'%m')='04' then 1 else 0 end) as val04,
sum(case when date_format(created_at,'%m')='05' then 1 else 0 end) as val05,
sum(case when date_format(created_at,'%m')='06' then 1 else 0 end) as val06,
sum(case when date_format(created_at,'%m')='07' then 1 else 0 end) as val07,
sum(case when date_format(created_at,'%m')='08' then 1 else 0 end) as val08,
sum(case when date_format(created_at,'%m')='09' then 1 else 0 end) as val09,
sum(case when date_format(created_at,'%m')='10' then 1 else 0 end) as val10,
sum(case when date_format(created_at,'%m')='11' then 1 else 0 end) as val11,
sum(case when date_format(created_at,'%m')='12' then 1 else 0 end) as val12,
count(*) as total 
from reservations
group by date_format(created_at,'%Y')

答案 1 :(得分:0)

您可以尝试以下查询

SELECT YEAR,SUM(VAL01) VAL02,SUM(VAL02) VAL02,SUM(VAL03) VAL3
FROM
(
       SELECT date_format(created_at,'%Y') YEAR,
      CASE WHEN date_format(created_at,'%m')=1 THEN 1 ELSE 0 END AS VAL01,
      CASE WHEN date_format(created_at,'%m')=2 THEN 1 ELSE 0 END AS VAL02,
       CASE WHEN date_format(created_at,'%m')=3 THEN 1 ELSE 0 END AS VAL03
       FROM reservations 

)t
 GROUP BY YEAR

希望这会有所帮助。

答案 2 :(得分:0)

如果这是Oracle,您可以在列Created_at上使用基于函数的索引,并在查询中使用相同的函数(在本例中为EXTRACT):

CREATE INDEX IDX1 ON RESERVATIONS (EXTRACT(YEAR FROM CREATED_AT))

由于这是MySQL,请尝试使用this作为替代方案。确保在创建索引后,通过验证查询计划来使用它。

答案 3 :(得分:0)

您可以尝试此查询

SELECT id, 
       Year, 
       SUM(CASE WHEN Month='01' THEN MonthCount ELSE 0 END) AS 'VAL01',
       SUM(CASE WHEN Month='02' THEN MonthCount ELSE 0 END) AS 'VAL02',
       SUM(CASE WHEN Month='03' THEN MonthCount ELSE 0 END) AS 'VAL03',
       SUM(CASE WHEN Month='04' THEN MonthCount ELSE 0 END) AS 'VAL04',
       SUM(CASE WHEN Month='05' THEN MonthCount ELSE 0 END) AS 'VAL05',
       SUM(CASE WHEN Month='06' THEN MonthCount ELSE 0 END) AS 'VAL06',
       SUM(CASE WHEN Month='07' THEN MonthCount ELSE 0 END) AS 'VAL07',
       SUM(CASE WHEN Month='08' THEN MonthCount ELSE 0 END) AS 'VAL08',
       SUM(CASE WHEN Month='09' THEN MonthCount ELSE 0 END) AS 'VAL09',
       SUM(CASE WHEN Month='10' THEN MonthCount ELSE 0 END) AS 'VAL10',
       SUM(CASE WHEN Month='11' THEN MonthCount ELSE 0 END) AS 'VAL11',
       SUM(CASE WHEN Month='12' THEN MonthCount ELSE 0 END) AS 'VAL12',
       SUM(MonthCount) AS Total        
FROM ( 
           SELECT 
                    CASE 
                             WHEN Date_format(created_at, '%Y') = '2016' THEN 1 
                             WHEN Date_format(created_at, '%Y') = '2017' THEN 2 
                             WHEN Date_format(created_at, '%Y') = '2018' THEN 3 
                    END                           AS id, 
                    Date_format(created_at, '%Y') AS Year, 
                    Date_format(created_at, '%m') AS Month, 
                    COUNT(1)                      AS MonthCount 
           FROM     reservations 
           WHERE    Date_format(created_at, '%Y') IN ('2016', '2017', '2018') 
           GROUP BY Date_format(created_at, '%Y-%m')) AS ByMonth 
GROUP BY id, Year