本文介绍group by配合聚合函数在实际项目中的实例。
先模拟生成一个表模拟用户的交易记录,分别有交易日,序列号,用户ID,交易金额四个字段,并设置交易日,序列号,用户ID为联合主键。并插入一些测试数据,两名用户的共7条交易数据。
Q:现要求能够输出每个用户最后一个交易(即交易日最新,并且序列号为该交易日最大)的交易详细的SQL语句。
DDL如下:
CREATE TABLE IF NOT EXISTS trade_history(
BASE_DATE DATE NOT NULL,
SEQUENCE INT NOT NULL,
USER_ID INT NOT NULL ,
TRADE_AMOUNT INT NOT NULL,
PRIMARY KEY(BASE_DATE,SEQUENCE,USER_ID)
);
按照题目要求,不难得出输出结果应为下图的两行数据。
求解过程
SELECT
MAX(BASE_DATE) AS BASE_DATE,SEQUENCE,USER_ID
FROM
TRADE_HISTORY
GROUP BY
USER_ID,SEQUENCE
输出如下如图:
-
步骤②:使用步骤①得到的结果和原数据结合(INNER JOIN),结合的条件为,交易日,序列号以及用户ID相同。JOIN后得到的结果集,也就只剩下了每个用户最新交易日的数据。这时再使用交易日和用户ID作为分组条件,用MAX()函数来求最大序列号即可。
结合图:
DML如下:
SELECT
TH1.BASE_DATE,MAX(TH1.SEQUENCE) AS SEQUENCE,TH1.USER_ID
FROM
TRADE_HISTORY TH1
INNER JOIN
(
SELECT
MAX(BASE_DATE) AS BASE_DATE,SEQUENCE,USER_ID
FROM
TRADE_HISTORY
GROUP BY
USER_ID,SEQUENCE
) TH2
ON
TH1.BASE_DATE = TH2.BASE_DATE
AND
TH1.USER_ID = TH2.USER_ID
GROUP BY
TH1.BASE_DATE,TH1.USER_ID
上述DML的输出结果如下图:
可见此时,每个用户的最新交易日和该交易日的最大交易序列号,都已经得到了。
结合图(红框内为结合条件):
最终DML语句,也是本问的解如下:
SELECT
TH.BASE_DATE,TH.SEQUENCE,TH.USER_ID,TH.TRADE_AMOUNT
FROM
TRADE_HISTORY TH
INNER JOIN
(
SELECT
TH1.BASE_DATE,MAX(TH1.SEQUENCE) AS SEQUENCE,TH1.USER_ID
FROM
TRADE_HISTORY TH1
INNER JOIN
(
SELECT
MAX(BASE_DATE) AS BASE_DATE,SEQUENCE,USER_ID
FROM
TRADE_HISTORY
GROUP BY
USER_ID,SEQUENCE
) TH2
ON
TH1.BASE_DATE = TH2.BASE_DATE
AND
TH1.USER_ID = TH2.USER_ID
GROUP BY
TH1.BASE_DATE,TH1.USER_ID
)TH3
ON
TH.BASE_DATE = TH3.BASE_DATE
AND
TH.SEQUENCE = TH3.SEQUENCE
AND
TH.USER_ID = TH3.USER_ID