这是架构:
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中的一些重要事实。
答案 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。