2

顧客プロファイルの変更を追跡するテーブルがあります。簡略化されたバージョンは次のとおりです。

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 月に 3 つの変更を行いました。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'その月の最新ではないためです。

4

3 に答える 3

2
SELECT  DISTINCT
CUSTOMER_ID,
EXTRACT(YEAR FROM DATE_CHANGED) AS YEAR,
EXTRACT(MONTH FROM DATE_CHANGED) AS MONTH,
LAST_VALUE(ACCOUNT_TYPE) 
OVER(PARTITION BY CUSTOMER_ID,TO_CHAR(DATE_CHANGED,'YYYY-MM') ORDER BY DATE_CHANGED ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS ACCOUNT_TYPE
FROM HISTORY



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

http://www.sqlfiddle.com/#!4/fab60/13

于 2013-05-08T09:20:18.190 に答える
2
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 |

http://sqlfiddle.com/#!4/e493a/15

于 2013-05-08T09:07:48.297 に答える
1
SELECT YEAR, MONTH, CUSTOMER_ID, ACCOUNT_TYPE
FROM 
(
SELECT EXTRACT(YEAR FROM DATE_CHANGED) AS YEAR,
       EXTRACT(MONTH FROM DATE_CHANGED) AS MONTH,
       CUSTOMER_ID, 
       ACCOUNT_TYPE,
       ROW_NUMBER() OVER (PARTITION BY CUSTOMER_ID, 
                                       EXTRACT(YEAR FROM DATE_CHANGED),
                                       EXTRACT(MONTH FROM DATE_CHANGED)
                          ORDER BY EXTRACT(YEAR FROM DATE_CHANGED) DESC,
                                   EXTRACT(MONTH FROM DATE_CHANGED) DESC,
                                   DATE_CHANGED DESC) RN
FROM   HISTORY
)
WHERE RN = 1
ORDER BY YEAR, MONTH, CUSTOMER_ID

出力

╔══════╦═══════╦═════════════╦══════════════╗
║ YEAR ║ MONTH ║ CUSTOMER_ID ║ ACCOUNT_TYPE ║
╠══════╬═══════╬═════════════╬══════════════╣
║ 2013 ║     1 ║         200 ║ Premium      ║
║ 2013 ║     2 ║         300 ║ Free         ║
║ 2013 ║     3 ║         100 ║ Premium      ║
║ 2013 ║     3 ║         200 ║ Standard     ║
╚══════╩═══════╩═════════════╩══════════════╝
于 2013-05-08T09:08:30.843 に答える