mysql的动态列创建
我已经为MYSQL编写了以下查询:mysql的动态列创建,mysql,Mysql,我已经为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
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
它按预期输出表格,其中包含一列开始日期、累计申请数量和年份:
我想做的是删除类似“2016%”的数据,这样我就可以得到所有年份的数据,最后得到一个如下表:
等等。这个问题的累积性质使得它与大多数其他关键问题截然不同。以下是一种每年使用单独变量的方法:
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;
编辑:
有时,分组依据
和变量不能一起工作。这是使用子查询修复的:
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;
以下是一个完整演示的解决方案:
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;
下面是一个演示:
SQL:
输出:
这个问题可能是其他问题的重复,但不是原来的问题。这是在列中要求累计金额。谢谢,有没有一种方法可以在我不必每年手动编码的情况下完成它?它将自动调用“添加多年的行”?@StevenStangle。这需要动态SQL,而且会更加复杂,因为pivot的累积求和特性。实际上我运行了它,它也没有进行求和。我想这些可能是一天的计数,不是正确的累积。那很好,这将在PHP中,所以我可以写一个循环来生成年份,但累积部分是关闭的。
-- 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)