两个表中的SUM IF不反映正确的数字

时间:2018-02-07 05:09:03

标签: mysql

这是架构:

CREATE TABLE purchases_2018_1 (
  name varchar(20), 
  units SMALLINT, 
  ts int
);
INSERT INTO purchases_2018_1 (name, units, ts) 
  VALUES
    ('John', 1, UNIX_TIMESTAMP('2018-01-03 12:00:00')),
    ('John', 2, UNIX_TIMESTAMP('2018-01-04 12:00:00')),
    ('John', 1, UNIX_TIMESTAMP('2018-01-01 12:00:00')),
    ('John', 1, UNIX_TIMESTAMP('2018-01-01 12:00:00')), # histSum = 20 instead of 5
    ('Jill', 1, UNIX_TIMESTAMP('2018-01-01 12:00:00')),
    ('Jill', 1, UNIX_TIMESTAMP('2018-01-01 12:00:00')),
    ('Jill', 1, UNIX_TIMESTAMP('2018-01-20 12:00:00')),
    ('Jill', 2, UNIX_TIMESTAMP('2018-01-13 12:00:00')), # histSum = 20 instead of 5            
    ('Jack', 10, UNIX_TIMESTAMP('2018-01-08 12:00:00')), # histSum = 10 (correct)
    ('Jean', 1, UNIX_TIMESTAMP('2018-01-11 12:00:00')); # histSum = 1 (correct)

CREATE TABLE purchases_2018_2 (name varchar(20), units SMALLINT, ts int);
INSERT INTO purchases_2018_2 (name, units, ts) 
  VALUES
    ('John', 1, UNIX_TIMESTAMP('2018-02-01 00:00:00')),
    ('John', 4, UNIX_TIMESTAMP('2018-02-01 00:00:00')),
    ('John', 1, UNIX_TIMESTAMP('2018-02-07 10:00:00')),
    ('John', 1, UNIX_TIMESTAMP('2018-02-07 10:00:00')), # currSum = 8 instead of 2
    ('Jill', 7, UNIX_TIMESTAMP('2018-02-07 10:00:00')),
    ('Jill', 1, UNIX_TIMESTAMP('2018-02-07 10:00:00')), # currSum = 32 instead of 8
    ('Jill', 1, UNIX_TIMESTAMP('2018-02-01 00:00:00')),
    ('Jill', 1, UNIX_TIMESTAMP('2018-02-01 00:00:00')),            
    ('Jack', 7, UNIX_TIMESTAMP('2018-02-07 10:00:00')), # currSum = 7 (correct)
    ('Jean', 1, UNIX_TIMESTAMP('2018-02-01 00:00:00')); # currSum = 0 (correct)

以下是查询:

SELECT
    jan.name,
    SUM(IF(jan.ts BETWEEN UNIX_TIMESTAMP('2018-01-01 00:00:00') AND UNIX_TIMESTAMP('2018-02-01 00:00:00'), jan.units, 0)) AS histSum,
    SUM(IF(feb.ts BETWEEN UNIX_TIMESTAMP('2018-02-07 07:00:00') AND UNIX_TIMESTAMP('2018-02-07 12:00:00'), feb.units, 0)) AS currSum
FROM purchases_2018_1 AS jan 
JOIN purchases_2018_2 AS feb 
ON jan.name = feb.name
GROUP BY jan.name;

结果如下:

name    histSum currSum
Jack    10      7
Jean    1       0
Jill    20      32
John    20      8

这是SQL Fiddle。 我肯定做错了什么。任何人都可以伸出援手吗?我一定错过了SQL中的一些重要事实。

2 个答案:

答案 0 :(得分:1)

您需要使用UNION组合两个表的行,而不是将它们连接起来,

SELECT  Name,
        MAX(CASE WHEN MTH = 'Jan' THEN TotalUnit ELSE 0 END) histSum, 
        MAX(CASE WHEN MTH = 'Feb' THEN TotalUnit ELSE 0 END) currSum
FROM
        (
            SELECT  name, 
                    SUM(units) TotalUnit,
                    'Jan' AS MTH
            FROM    purchases_2018_1
            WHERE   ts BETWEEN UNIX_TIMESTAMP('2018-01-01 00:00:00') 
                    AND UNIX_TIMESTAMP('2018-02-01 00:00:00')
            GROUP   BY name
            UNION   ALL
            SELECT  name, 
                    SUM(units) TotalUnit,
                    'Feb' AS MTH
            FROM    purchases_2018_2
            WHERE   ts BETWEEN UNIX_TIMESTAMP('2018-02-07 07:00:00') 
                    AND UNIX_TIMESTAMP('2018-02-07 12:00:00')
            GROUP   BY name
        ) subquery
GROUP   BY Name

这里是Demo

答案 1 :(得分:0)

另一种方法:

SELECT  JanResult.Name,
        JanResult.histSum, 
        FebResult.currSum 
FROM
        (
            SELECT
                jan.name As Name,
                SUM(IF(jan.ts BETWEEN UNIX_TIMESTAMP('2018-01-01 00:00:00') AND UNIX_TIMESTAMP('2018-02-01 00:00:00'), jan.units, 0)) AS histSum
            FROM purchases_2018_1 AS jan 
            GROUP BY jan.name
        ) as JanResult
        INNER JOIN
        (
            SELECT
                feb.name As Name,
                SUM(IF(feb.ts BETWEEN UNIX_TIMESTAMP('2018-02-07 07:00:00') AND UNIX_TIMESTAMP('2018-02-07 12:00:00'), feb.units, 0)) AS currSum
            FROM purchases_2018_2 AS feb 
            GROUP BY feb.name
        ) as FebResult
        ON JanResult.Name = FebResult.Name;

SQL小提琴here

相关问题