mysql - 跨 2 个表的 SUM IF 未反射(reflect)正确的数字

标签 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 中的一些重要事实。

最佳答案

您需要使用 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

关于mysql - 跨 2 个表的 SUM IF 未反射(reflect)正确的数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48656401/

相关文章:

php - 融合图表中一个网页中的多个图表

c# - 从多个 sql 表 Entity Framework web api 返回数据

mysql - 在 MySql 中,如何将数据插入到引用其他三个表的表中,然后选择该数据?

mysql - 使用本地 MySQL 数据库更新远程 MySQL 数据库

mysql - 如何获取 Prestashop 中已选择属性的所有产品

mysql - Laravel 中如何通过数据透视表获取相关模型?

mysql - docker + MySQL 8 : connection issues

php - 如何定义进入 $_POST[] 的关联数组?

php mysql查询编码问题

mysql - 按没有子查询的最大时间分组