MySQL:来自不同子查询的多个运行总计

时间:2016-02-05 14:35:49

标签: mysql running-total

当我使用以下公式运行单个查询以使第一列回馈月/年时,第二列回报每月签名的人数,第三列回报签名者的运行总数,它的工作原理大:

SET @runtot1:=0;
SELECT
   1rt.MONTH,
   1rt.1signed,
   (@runtot1 := @runtot1 + 1rt.1signed) AS 1rt
FROM 
   (SELECT
       DATE_FORMAT(STR_TO_DATE(s.datecontacted,'%m/%d/%Y'),'%Y-%m') AS MONTH,
       IFNULL(COUNT(DISTINCT CASE WHEN s.surveyid = 791796 THEN s.id ELSE NULL END),0) AS 1signed
    FROM  table1 s
    JOIN table2 m ON s.id = m.id AND m.current = "Yes"
    WHERE STR_TO_DATE(s.datecontacted,'%m/%d/%Y') > '2015-03-01'
    GROUP  BY MONTH
    ORDER  BY MONTH) AS 1rt

通过上面的查询,我得到了以下结果表,如果我只需要计算一件事,这就是我想要的结果:

MONTH   1signed 1rt
2015-03 0       0
2015-04 1       1
2015-05 0       1
2015-08 1       2
2015-10 1       3
2015-11 1       4
2016-01 0       4
2016-02 0       4

但我无法弄清楚如何使用多个子查询来实现这一点,因为我需要同时对多个列进行此操作。例如,我正在尝试这样的事情(which doesn't work):

SET @runtot1:=0;
SET @runtot2:=0;
select 
  DATE_FORMAT(STR_TO_DATE(s1.datecontacted,'%m/%d/%Y'),'%Y-%m') AS MONTH,
  t1.1signed,
  (@runtot1 := @runtot1 + t1.1signed) AS 1rt,
  t2.2signed,
  (@runtot2 := @runtot2 + t2.2signed) AS 2rt
from
    (select 
     DATE_FORMAT(STR_TO_DATE(s.datecontacted,'%m/%d/%Y'),'%Y-%m') AS MONTH,
     IFNULL(COUNT(DISTINCT CASE WHEN s.surveyid = 791796 THEN s.id ELSE NULL END),0) AS 1signed
     from table1 s 
     left join table2 m ON m.id = s.id
     where m.current = "Yes"
     GROUP BY MONTH
     ORDER BY MONTH) as T1,
     (select 
     DATE_FORMAT(STR_TO_DATE(s.datecontacted,'%m/%d/%Y'),'%Y-%m') AS MONTH,
     IFNULL(COUNT(DISTINCT CASE WHEN s.surveyid = 846346 THEN s.id ELSE NULL END),0) AS 2signed
     from table1 s 
     left join table2 m ON m.id = s.id
     where m.current = "Yes"
     GROUP BY MONTH
     ORDER BY MONTH) as T2,
     table1 s1
LEFT JOIN table2 m1 ON m1.id = s1.id AND m1.current = "Yes"
WHERE STR_TO_DATE(s1.datecontacted,'%m/%d/%Y') > '2015-03-01'
GROUP BY DATE_FORMAT(STR_TO_DATE(s1.datecontacted,'%m/%d/%Y'),'%Y-%m')
ORDER BY DATE_FORMAT(STR_TO_DATE(s1.datecontacted,'%m/%d/%Y'),'%Y-%m')

这严重破坏了我的结果 - 我也尝试了LEFT JOIN以使这两个相互接触,但这也没有用。

这是一个 SQL Fiddle ,其中包含一些值,顶部的查询可以使用,但不是查询下面需要的查询。

如果代码的多子查询版本有效,则下面将是理想的最终结果:

MONTH   1signed 1rt 2signed 2rt
2015-03 0       0   1       1
2015-04 1       1   0       1
2015-05 0       1   1       2
2015-08 1       2   0       2
2015-10 1       3   0       2
2015-11 1       4   0       2
2016-01 0       4   0       2
2016-02 0       4   1       3

尝试找出一种方法,使用相同的查询,针对两个不同的调查问题,从2015年3月开始按月计算滚动总数。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

你的尝试实际上非常接近。我刚刚摆脱了S1并在MONTH列上将两个子查询连接在一起:

SET @runtot1:=0;
SET @runtot2:=0;
select 
  T1.MONTH,
  t1.1signed,
  (@runtot1 := @runtot1 + t1.1signed) AS 1rt,
  t2.2signed,
  (@runtot2 := @runtot2 + t2.2signed) AS 2rt
from
    (select 
     DATE_FORMAT(STR_TO_DATE(s.datecontacted,'%m/%d/%Y'),'%Y-%m') AS MONTH,
     IFNULL(COUNT(DISTINCT CASE WHEN s.surveyid = 791796 THEN s.id ELSE NULL END),0) AS 1signed
     from table1 s 
     left join table2 m ON m.id = s.id
     where m.current = "Yes" and STR_TO_DATE(s.datecontacted,'%m/%d/%Y') > '2015-03-01'
     GROUP BY MONTH
     ORDER BY MONTH) as T1,
     (select 
     DATE_FORMAT(STR_TO_DATE(s.datecontacted,'%m/%d/%Y'),'%Y-%m') AS MONTH,
     IFNULL(COUNT(DISTINCT CASE WHEN s.surveyid = 846346 THEN s.id ELSE NULL END),0) AS 2signed
     from table1 s 
     left join table2 m ON m.id = s.id
     where m.current = "Yes" and STR_TO_DATE(s.datecontacted,'%m/%d/%Y') > '2015-03-01'
     GROUP BY MONTH
     ORDER BY MONTH) as T2
WHERE 
T1.MONTH=T2.MONTH
GROUP BY T1.MONTH
ORDER BY T1.MONTH

我还没有测试过Strawberry的解决方案,看起来更优雅。但我想你想知道你的方法(单独解决运行总数,然后将结果加在一起)也会有效。

答案 1 :(得分:0)

似乎你在追求这样的事情......

数据集:

DROP TABLE IF EXISTS table1;

CREATE TABLE table1
( id INT NOT NULL
, date_contacted DATE NOT NULL
, survey_id INT NOT NULL
, PRIMARY KEY(id,survey_id)
);

DROP TABLE IF EXISTS table2;

CREATE TABLE table2
(id INT NOT NULL PRIMARY KEY
,is_current TINYINT NOT NULL DEFAULT 0
);

INSERT INTO table1 VALUES
(1,"2015-03-05",846346),
(2,"2015-04-15",791796),
(2,"2015-05-04",846346),
(3,"2015-06-07",791796),
(3,"2015-06-08",846346),
(4,"2015-08-02",791796),
(5,"2015-10-15",791796),
(6,"2015-11-25",791796),
(6,"2016-01-02", 11235),
(6,"2016-02-06",846346);

INSERT INTO table2 (id,is_current) VALUES
(1,1),
(2,1),
(3,0),
(4,1),
(5,1),
(6,1);

查询:

SELECT x.*
     , @a:=@a+a rt_a
     , @b:=@b+b rt_b
  FROM 
     ( SELECT DATE_FORMAT(date_contacted,'%Y-%m') month
            , SUM(survey_id = 791796) a
            , SUM(survey_id = 846346) b
         FROM table1 x 
         JOIN table2 y 
           ON y.id = x.id 
        WHERE y.is_current = 1
        GROUP 
           BY month
     ) x
  JOIN (SELECT @a:=0,@b:=0) vars
 ORDER 
    BY month;
+---------+------+------+------+------+
| month   | a    | b    | rt_a | rt_b |
+---------+------+------+------+------+
| 2015-03 |    0 |    1 |    0 |    1 |
| 2015-04 |    1 |    0 |    1 |    1 |
| 2015-05 |    0 |    1 |    1 |    2 |
| 2015-08 |    1 |    0 |    2 |    2 |
| 2015-10 |    1 |    0 |    3 |    2 |
| 2015-11 |    1 |    0 |    4 |    2 |
| 2016-01 |    0 |    0 |    4 |    2 |
| 2016-02 |    0 |    1 |    4 |    3 |
+---------+------+------+------+------+