Sql server 在规定时间内满足规定要求的项目

Sql server 在规定时间内满足规定要求的项目,sql-server,Sql Server,朋友们: 我有一个关于SQL Server查询的问题 对于DCFlg='Credit',表示客户在银行存款,DCFlag='Debit'表示客户从银行取款 我想从交易记录中找到一些客户,如果客户在银行存了一些钱,并且在3天内没有提取一半 以下是一些交易记录示例: TransactionNo AccountNo DCFlag TransactionDateTime TransactionBaseAmount A000001 A1 CREDIT 2

朋友们:

我有一个关于SQL Server查询的问题

对于DCFlg='Credit',表示客户在银行存款,DCFlag='Debit'表示客户从银行取款

我想从交易记录中找到一些客户,如果客户在银行存了一些钱,并且在3天内没有提取一半

以下是一些交易记录示例:

TransactionNo   AccountNo   DCFlag  TransactionDateTime    TransactionBaseAmount
A000001           A1        CREDIT  2015/9/17 16:24:11      $1,000
A000002           A1        DEBIT   2015/9/18 16:24:11      $200
A000003           A1        DEBIT   2015/9/19 16:24:11      $100
A000004           B1        DEBIT   2015/10/22 8:18:46      $1000
A000005           B1        CREDIT  2015/10/22 10:18:46     $500
A000006           C1        CREDIT  2015/10/22 8:18:46      $1,000
A000007           C1        DEBIT   2015/10/22 10:18:46     $900
A000008           C1        CREDIT  2015/10/22 18:18:46     $950
A000009           D1        DEBIT   2013/11/21 19:43:50     $1,000
A000010           D1        CREDIT  2013/11/21 20:43:50     $600
A000011           D1        DEBIT   2013/11/22 19:43:50     $400
我想要的结果是:

AccountNo
A1
B1
C1
我尝试了我的SQL:

WITH Cre AS
(
SELECT AccountNo,cast(TransactionDateTime as date) TxnDate,SUM(TransactionBaseAmount) Cre_Amount
FROM mytable 
WHERE DCFlag = 'Credit' 
group by AccountNo,cast(TransactionDateTime as date)
),
Deb AS
(
SELECT AccountNo,cast(TransactionDateTime as date) TxnDate,SUM(TransactionBaseAmount) Deb_Amount
FROM mytable 
WHERE DCFlag = 'Debit' 
group by AccountNo,cast([TransactionDateTime] as date)
)
SELECT A.AccountNo
FROM Cre A,
 Deb D,
 Deb E,
 Deb F
WHERE A.TxnDate = DATEADD(D,1,E.TxnDate) AND A.TxnDate = DATEADD(D,2,F.TxnDate)
AND A.TxnDate = D.TxnDate
AND A.AccountNo = D.AccountNo
AND A.AccountNo = E.AccountNo
AND A.AccountNo = F.AccountNo
GROUP BY A.AccountNo,A.TxnDate,
D.AccountNo,D.TxnDate,
E.AccountNo,E.TxnDate,
F.AccountNo,F.TxnDate,
A.Cre_Amount,D.Deb_Amount,E.Deb_Amount,F.Deb_Amount
HAVING A.Cre_Amount>(D.Deb_Amount+E.Deb_Amount+F.Deb_Amount)/2
group by AccountNo
我得到的结果是:

AccountNo
A1
C1
需求和结果之间的差异原因是TransactionNo=A000004,因为它是DCFlag=‘Debit’,我想要的是客户在银行存了一些钱后,他不会在3天内提取一半。 当我发现这个问题时,我会修改我的SQL:

WITH Cre AS
(
SELECT AccountNo,TransactionDateTime,TransactionBaseAmount
FROM T_I_ACCOUNT_TRANSACTION 
WHERE DCFlag = 'Credit' 
),
Deb AS
(
SELECT AccountNo,TransactionDateTime,TransactionBaseAmount
FROM T_I_ACCOUNT_TRANSACTION 
WHERE DCFlag = 'Debit' 
)
SELECT A.AccountNo
FROM Cre A,
 Deb D,
 Deb E,
 Deb F
WHERE cast(A.TransactionDateTime as date) =     DATEADD(D,1,cast(E.TransactionDateTime as date)) 
AND cast(A.TransactionDateTime as date) = DATEADD(D,2,cast(F.TransactionDateTime as date))
AND cast(A.TransactionDateTime as date) = cast(D.TransactionDateTime as date)
AND A.AccountNo = D.AccountNo
AND A.AccountNo = E.AccountNo
AND A.AccountNo = F.AccountNo
AND A.TransactionDateTime>D.TransactionDateTime
GROUP BY A.AccountNo,cast(A.TransactionDateTime as date),
D.AccountNo,cast(D.TransactionDateTime as date),
E.AccountNo,cast(E.TransactionDateTime as date),
F.AccountNo,cast(F.TransactionDateTime as date)
HAVING SUM(A.TransactionBaseAmount)>(SUM(D.TransactionBaseAmount)+SUM(E.TransactionBaseAmount)+SUM(F.TransactionBaseAmount))/2
对于第一个SQL,它在1分钟内完成。在最后一个SQL中,我运行了30多分钟,没有得到任何结果。因为实际数据更大,我取消了它,认为失败了


谁能帮我?

你可以做如下事情:

;with cre as (
    select * from (
        select *, sum(TransactionBaseAmount) over (partition by AccountNo, DCFlag) sumover  
                , max(TransactionDateTime)over (partition by AccountNo, DCFlag) maxdate
                , row_number() over (partition by AccountNo order by TransactionDateTime desc) rn
        from #t
        where DCFlag = 'CREDIT'
    )x
    where rn = 1
),
deb as (
    select    AccountNo,
              sum(TransactionBaseAmount) sumover  
            , max(TransactionDateTime) maxdate
    from #t
    where DCFlag = 'DEBIT'
    group by AccountNo
)
select cre.AccountNo
from cre 
join deb on cre.AccountNo = deb.AccountNo
where datediff(dd,cre.TransactionDateTime, deb.maxdate) <= 3 and cre.TransactionDateTime <= deb.maxdate and cre.sumover / 2 - deb.sumover >= 0
or cre.TransactionDateTime > deb.maxdate

您可以在以下位置进行测试:

您可以执行以下操作:

;with cre as (
    select * from (
        select *, sum(TransactionBaseAmount) over (partition by AccountNo, DCFlag) sumover  
                , max(TransactionDateTime)over (partition by AccountNo, DCFlag) maxdate
                , row_number() over (partition by AccountNo order by TransactionDateTime desc) rn
        from #t
        where DCFlag = 'CREDIT'
    )x
    where rn = 1
),
deb as (
    select    AccountNo,
              sum(TransactionBaseAmount) sumover  
            , max(TransactionDateTime) maxdate
    from #t
    where DCFlag = 'DEBIT'
    group by AccountNo
)
select cre.AccountNo
from cre 
join deb on cre.AccountNo = deb.AccountNo
where datediff(dd,cre.TransactionDateTime, deb.maxdate) <= 3 and cre.TransactionDateTime <= deb.maxdate and cre.sumover / 2 - deb.sumover >= 0
or cre.TransactionDateTime > deb.maxdate
您可以在以下位置进行测试: