SQL:计算过去3个月中每个月都有特定交易ID的帐户

时间:2017-05-01 21:18:21

标签: sql teradata

我有一个SQL脚本,它计算给定月份中具有特定事务ID的accts。我想修改它,以便只在过去3个月的每一个中放置这些类型的交易,而不仅仅是在任何给定月份,它只计算行为数。这是为了过滤掉一次性事件。

我对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

3 个答案:

答案 0 :(得分: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')

答案 1 :(得分: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

答案 2 :(得分: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

编辑:

基于评论,这不应该在固定的月份范围内进行,而是动态地,即计算每个月有多少账户在前两个月内也有交易?

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