admin

按客户和月份显示具有最新值的行

sql

我有一张表,可跟踪客户资料的变化。这是一个简化的版本

CREATE TABLE HISTORY (
    CUSTOMER_ID NUMBER(9,0), 
    DATE_CHANGED DATE, 
    ACCOUNT_TYPE VARCHAR2(20),

    CONSTRAINT HISTORY_PK PRIMARY KEY (CUSTOMER_ID, DATE_CHANGED)
);

INSERT INTO HISTORY (CUSTOMER_ID, DATE_CHANGED, ACCOUNT_TYPE) VALUES (200, TO_DATE('05/01/2013 00:00:00','DD/MM/RRRR HH24:MI:SS'), 'Premium');
INSERT INTO HISTORY (CUSTOMER_ID, DATE_CHANGED, ACCOUNT_TYPE) VALUES (300, TO_DATE('17/02/2013 00:00:00','DD/MM/RRRR HH24:MI:SS'), 'Free');
INSERT INTO HISTORY (CUSTOMER_ID, DATE_CHANGED, ACCOUNT_TYPE) VALUES (100, TO_DATE('05/03/2013 00:00:00','DD/MM/RRRR HH24:MI:SS'), 'Free');
INSERT INTO HISTORY (CUSTOMER_ID, DATE_CHANGED, ACCOUNT_TYPE) VALUES (100, TO_DATE('12/03/2013 00:00:00','DD/MM/RRRR HH24:MI:SS'), 'Standard');
INSERT INTO HISTORY (CUSTOMER_ID, DATE_CHANGED, ACCOUNT_TYPE) VALUES (200, TO_DATE('22/03/2013 00:00:00','DD/MM/RRRR HH24:MI:SS'), 'Standard');
INSERT INTO HISTORY (CUSTOMER_ID, DATE_CHANGED, ACCOUNT_TYPE) VALUES (100, TO_DATE('29/03/2013 00:00:00','DD/MM/RRRR HH24:MI:SS'), 'Premium');

该数据由第三方维护。我的最终目标是在给定的时间范围内按帐户类型和月份获得客户总数,但到目前为止,我想从更简单的方法开始-
在变化的每个月/客户组合中显示最新的帐户类型记录:

YEAR MONTH CUSTOMER_ID ACCOUNT_TYPE
==== ===== =========== ============
2013     1         200 Premium
2013     2         300 Free
2013     3         100 Premium
2013     3         200 Standard

在这里,客户100在三月份进行了三处更改;我们显示“高级”,因为它具有3月内的最新日期。

获取 所有 行的查询将是这样的:

SELECT EXTRACT(YEAR FROM DATE_CHANGED) AS YEAR,
EXTRACT(MONTH FROM DATE_CHANGED) AS MONTH,
CUSTOMER_ID, ACCOUNT_TYPE
FROM HISTORY
ORDER BY YEAR, MONTH, CUSTOMER_ID, DATE_CHANGED

是否可以使用聚合函数过滤掉不需要的行?使用解析函数是否更有意义?

(并且,无论哪种情况,适当的功能是什么?)

编辑: 我被要求提供不需要的行的示例。3月,客户100有3行:

'05/03/2013 00:00:00', 'Free'
'12/03/2013 00:00:00', 'Standard'
'29/03/2013 00:00:00', 'Premium'

不需要的行是'Free''Standard'因为它们不是该月的最新行。


阅读 233

收藏
2021-07-01

共1个答案

admin

SELECT YEAR
,MONTH
,customer_id
,max(ACCOUNT_TYPE) keep(dense_rank FIRST ORDER BY date_changed DESC) LAST_ACC
FROM (
SELECT EXTRACT(YEAR FROM DATE_CHANGED) AS YEAR,
EXTRACT(MONTH FROM DATE_CHANGED) AS MONTH,
CUSTOMER_ID,
date_changed,
account_type
FROM HISTORY
)
GROUP BY YEAR, MONTH, customer_id
ORDER BY YEAR, MONTH, CUSTOMER_ID

| YEAR | MONTH | CUSTOMER_ID | LAST_ACC |
-----------------------------------------
| 2013 |     1 |         200 |  Premium |
| 2013 |     2 |         300 |     Free |
| 2013 |     3 |         100 |  Premium |
| 2013 |     3 |         200 | Standard |
2021-07-01