2017-05-01 3 views
2

特定の月に特定のトランザクションIDを持つアカウント数をカウントするSQLスクリプトがあります。私はこれを修正して、指定された月だけではなく、過去3か月のそれぞれにこれらのタイプのトランザクションを配置した場合には、acctsの数をカウントするようにします。これは、ワンタイムイベントを除外するためです。SQL:過去3か月間に特定のトランザクションIDが存在するアカウントをカウントする

私はかなり新しいSQLで、私が行った検索を通して明確な答えを見つけることができませんでした。助けていただければ幸いです。ありがとう!

SELECT 
    CLDR.YEAR_MONTH 
    ,COUNT(DISTINCT TRAN.ACCT_NBR) AS IC_DD --counts all unique Acct numbers 

FROM 
    REPORTS.FINANCIAL_TRAN AS TRAN 

INNER JOIN REPORTS.ACCT AS ACCT ON TRAN.ACCT_NBR=ACCT.ACCT_NBR 
INNER JOIN REPORTS.DATE AS CLDR ON TRAN.TRAN_DT=CLDR.CALENDAR_DATE 

WHERE 
    TRAN.TRAN_CD IN ('id1','id2','id3') --Filters on Transaction IDs 
AND 
    TRAN.TRAN_DT BETWEEN '2017-01-01' AND '2017-03-31' 

GROUP BY 
    CLDR.YEAR_MONTH 

ORDER BY 
    CLDR.YEAR_MONTH 

答えて

0

あなたはACCTとカレンダーテーブルの両方に参加する必要はありません。

SELECT Count(*) 
FROM 
(
    SELECT ACCT_NBR 
    FROM REPORTS.FINANCIAL_TRAN AS TRAN 
    WHERE 
     TRAN.TRAN_CD IN ('id1','id2','id3') --Filters on Transaction IDs 
    AND 
     TRAN.TRAN_DT BETWEEN '2017-01-01' AND '2017-03-31' 
    GROUP BY ACCT_NBR 
    -- rows for all three months exist for this account 
    HAVING Count(DISTINCT EXTRACT(MONTH FROM tran_dt)) = 3 
) AS dt 

は編集:コメントはこれに基づき

は数ヶ月の一定の範囲のために行われるべきではありません、動的には、つまり、毎月計算されたアカウント数が存在し、過去2ヶ月以内に取引があったか?

SELECT trans_month, Count(*) 
FROM 
(
    SELECT 
     ACCT_NBR, 
    ,Trunc(TRAN_DT, 'mon') AS trans_month -- 1st of month 
    FROM TRAN 
    WHERE 
     TRAN.TRAN_CD IN ('id1','id2','id3') --Filters on Transaction IDs 
-- AND 
--  TRAN.TRAN_DT BETWEEN '2017-01-01' AND '2017-03-31' 
    GROUP BY ACCT_NBR, trans_month -- distinct list first 
    QUALIFY 
     -- check if there are three consecutive months 
     -- e.g. 
     -- 2017-02-01 <- 2 preceding, must be 2 months before current row 
     -- 2017-03-01 <- 1 preceding 
     -- 2017-04-01 <- current row 
     Min(trans_month) 
     Over (PARTITION BY ACCT_NBR 
      ORDER BY trans_month 
      ROWS 2 Preceding) = Add_Months(trans_month,-2) 
) AS dt 
GROUP BY trans_month 
ORDER BY trans_month 
+0

それはトリックでした。私はちょうどそれがデータのプルダウンカレンダーの結果を表示する方法を把握します。ありがとう! – starfly

+0

@starfly:どのカレンダーの結果、 'DATE '2017-01-01''?あなたはハードコーディングされた日付範囲を持っていて、毎月の行を持つ顧客を数えたいと思っています – dnoeth

+0

YYYYMMという形式の日付列を持っています(これがCLDRに加入した理由です)。 TRAN_DTの場合、過去3ヶ月を引き出します。したがって、CLDR月が201703の場合は、TRAN_DT 2017-01-01 - 2017-03-31; CLDR月が201702の場合は、TRAN_DT 2016-12-01 - 2017-02-28を引き出します。そうする簡単な方法はありますか? – starfly

0

強引なアプローチは、各月のIN句を追加するために、次のようになります。ここでは

AND TRAN.ACCT_NBR IN (
     SELECT ACCT_NBR 
     FROM REPORTS.FINANCIAL_TRAN 
     WHERE TRAN_DT BETWEEN '2017-01-01' AND '2017-01-31') 
AND TRAN.ACCT_NBR IN (
     SELECT ACCT_NBR 
     FROM REPORTS.FINANCIAL_TRAN 
     WHERE TRAN_DT BETWEEN '2017-02-01' AND '2017-02-28') 
AND TRAN.ACCT_NBR IN (
     SELECT ACCT_NBR 
     FROM REPORTS.FINANCIAL_TRAN 
     WHERE TRAN_DT BETWEEN '2017-03-01' AND '2017-03-31') 
+0

これはWHERE句の一部になりますか?私はそれが私に望ましい結果をもたらすかどうかを見るためにこれを試みます。 – starfly

0

は、私はMSSQLでそれを行うだろうかです。私はあなたがTeradataでウィンドウ機能を持っていることを確信しています。

私のテストのためにデータを簡略化していますが、これは正しい軌道に乗るはずです。 CTEの理由は、ウィンドウ関数でCOUNT DISTINCTを使用できないためです。

CREATE TABLE #Test (
    ACCT_NBR int 
    ,YEAR_MONTH char(5) 
    ,TRAN_DT datetime) 

INSERT INTO #Test 
SELECT 123, '17/01', '2017-01-11'; 
INSERT INTO #Test 
SELECT 123, '17/02', '2017-02-12'; 
INSERT INTO #Test 
SELECT 123, '17/02', '2017-02-21'; 
INSERT INTO #Test 
SELECT 123, '17/03', '2017-03-19'; 
INSERT INTO #Test 
SELECT 356, '17/01', '2017-01-14'; 
INSERT INTO #Test 
SELECT 356, '17/01', '2017-01-22'; 
INSERT INTO #Test 
SELECT 356, '17/03', '2017-03-14'; 

SELECT * FROM #Test; 

WITH CTE AS (
    SELECT DISTINCT 
     ACCT_NBR AS AccountNumber 
     ,YEAR_MONTH AS YYMM 
    FROM #Test 
    WHERE TRAN_DT BETWEEN '2017-01-01' AND '2017-03-31') 

SELECT DISTINCT 
    YYMM 
    ,COUNT(AccountNumber) OVER (PARTITION BY YYMM) AS Counts 
FROM CTE 
+0

ありがとうございます。私は残念ながら、DBMSへの書き込みアクセス権を持っていないので、(一時的な)テーブルを作成することはできません。 – starfly

+0

テーブル変数を使用します。または、許可を求める。または、単にuser7593937に例を示し、テーブルを使用できるという事実にアクセスしてください。 – Morzel

+0

一時テーブルは、使用するデータを試して複製するためのデータを提供するだけのものでした。このソリューションには一時テーブルは必要ありません。 CTEでクエリを使用してから、ウィンドウ関数を使用してカウントを実行してください。 – user7593937

関連する問題