我为MYSQL编写了以下查询:
SELECT DATE_FORMAT(start, '%m/%e') as start, (@total := @total + T.id) AS TotalApps, DATE_FORMAT(start, '%Y') as year FROM (SELECT start,COUNT(*) AS id FROM application WHERE start LIKE '2016%' GROUP BY MONTH(start), DAY(start)) AS T, (SELECT @total:=0) AS n
按预期输出表格,其中包含开始日期,累计申请数量和年份的列:
我要做的是删除LIKE'2016%'以便我可以获取所有年份的数据并最终得到一个表格如下:
等等。
答案 0 :(得分:1)
问题的累积性质使其与大多数其他枢轴问题完全不同。这是一种每年使用单独变量的方法:
SELECT DATE_FORMAT(start, '%m/%d') as mmdd,
(@t2016 := @t2016 + sum(year(start) = 2016)) as tot_2016,
(@t2015 := @t2015 + sum(year(start) = 2015)) as tot_2015,
(@t2014 := @t2014 + sum(year(start) = 2014)) as tot_2014
FROM application a CROSS JOIN
(SELECT @t2016 := 0, @t2015 := 0, @t2014 := 0) params
GROUP BY DATE_FORMAT(start, '%m/%d')
ORDER BY mmdd;
编辑:
有时,group by
和变量不能一起工作。这是使用子查询修复的:
SELECT mmdd,
(@t2016 := @t2016 + cnt_2016) as tot_2016,
(@t2015 := @t2015 + cnt_2015) as tot_2015,
(@t2014 := @t2014 + cnt_2014) as tot_2014
FROM (SELECT DATE_FORMAT(start, '%m/%d') as mmdd,
sum(year(start) = 2016)) as cnt_2016,
sum(year(start) = 2015)) as cnt_2015,
sum(year(start) = 2014)) as cnt_2014
FROM application a
GROUP BY DATE_FORMAT(start, '%m/%d')
ORDER BY mmdd
) x CROSS JOIN
(SELECT @t2016 := 0, @t2015 := 0, @t2014 := 0) params;
答案 1 :(得分:0)
这是一个完整的演示解决方案:
SELECT T2.month_day,
IF (SUM(TotalApps * (YEAR(start) = '2016')) = 0, '', SUM(TotalApps * (YEAR(start) = '2016'))) as `2016`,
IF (SUM(TotalApps * (YEAR(start) = '2015')) = 0, '', SUM(TotalApps * (YEAR(start) = '2015'))) as `2015`,
IF (SUM(TotalApps * (YEAR(start) = '2014')) = 0, '', SUM(TotalApps * (YEAR(start) = '2014'))) as `2014`,
IF (SUM(TotalApps * (YEAR(start) = '2013')) = 0, '', SUM(TotalApps * (YEAR(start) = '2013'))) as `2013`
FROM
( SELECT
start, month_day,
IF(@last_year = YEAR(start),
@total := @total + T.id,
@total := T.id) AS TotalApps,
@last_year := YEAR(start)
FROM (SELECT start,COUNT(*) AS id, DATE_FORMAT(start, '%m/%e') as month_day
FROM application
GROUP BY start
ORDER BY start) AS T, (SELECT @total:=0, @last_year := NULL) AS n
) as T2
GROUP BY month_day;
这是一个演示:
-- data
create table application(start date);
insert into application values
('2016-01-01'),('2016-01-02'),('2016-01-02'),('2016-01-03'),
('2014-01-01'),('2014-01-02'),('2014-01-04'),
('2015-01-01'),('2015-01-02'),('2015-01-05');
select * from application;
-- query wanted
SELECT T2.month_day,
IF (SUM(TotalApps * (YEAR(start) = '2016')) = 0, '', SUM(TotalApps * (YEAR(start) = '2016'))) as `2016`,
IF (SUM(TotalApps * (YEAR(start) = '2015')) = 0, '', SUM(TotalApps * (YEAR(start) = '2015'))) as `2015`,
IF (SUM(TotalApps * (YEAR(start) = '2014')) = 0, '', SUM(TotalApps * (YEAR(start) = '2014'))) as `2014`,
IF (SUM(TotalApps * (YEAR(start) = '2013')) = 0, '', SUM(TotalApps * (YEAR(start) = '2013'))) as `2013`
FROM
( SELECT
start, month_day,
IF(@last_year = YEAR(start),
@total := @total + T.id,
@total := T.id) AS TotalApps,
@last_year := YEAR(start)
FROM (SELECT start,COUNT(*) AS id, DATE_FORMAT(start, '%m/%e') as month_day
FROM application
GROUP BY start
ORDER BY start) AS T, (SELECT @total:=0, @last_year := NULL) AS n
) as T2
GROUP BY month_day
;
mysql> select * from application;
+------------+
| start |
+------------+
| 2016-01-01 |
| 2016-01-02 |
| 2016-01-02 |
| 2016-01-03 |
| 2014-01-01 |
| 2014-01-02 |
| 2014-01-04 |
| 2015-01-01 |
| 2015-01-02 |
| 2015-01-05 |
+------------+
10 rows in set (0.00 sec)
mysql> -- query wanted
mysql> SELECT T2.month_day,
-> IF (SUM(TotalApps * (YEAR(start) = '2016')) = 0, '', SUM(TotalApps * (YEAR(start) = '2016'))) as `2016`,
-> IF (SUM(TotalApps * (YEAR(start) = '2015')) = 0, '', SUM(TotalApps * (YEAR(start) = '2015'))) as `2015`,
-> IF (SUM(TotalApps * (YEAR(start) = '2014')) = 0, '', SUM(TotalApps * (YEAR(start) = '2014'))) as `2014`,
-> IF (SUM(TotalApps * (YEAR(start) = '2013')) = 0, '', SUM(TotalApps * (YEAR(start) = '2013'))) as `2013`
-> FROM
-> ( SELECT
-> start, month_day,
-> IF(@last_year = YEAR(start),
-> @total := @total + T.id,
-> @total := T.id) AS TotalApps,
-> @last_year := YEAR(start)
-> FROM (SELECT start,COUNT(*) AS id, DATE_FORMAT(start, '%m/%e') as month_day
-> FROM application
-> GROUP BY start
-> ORDER BY start) AS T, (SELECT @total:=0, @last_year := NULL) AS n
-> ) as T2
-> GROUP BY month_day
-> ;
+-----------+------+------+------+------+
| month_day | 2016 | 2015 | 2014 | 2013 |
+-----------+------+------+------+------+
| 01/1 | 1 | 1 | 1 | |
| 01/2 | 3 | 2 | 2 | |
| 01/3 | 4 | | | |
| 01/4 | | | 3 | |
| 01/5 | | 3 | | |
+-----------+------+------+------+------+
5 rows in set (0.00 sec)