2015-12-23 30 views
1

朋友:一個項目,以滿足在規定的時間規定的要求

我有一個關於SQL Server查詢問題

對於DCFlg =「信用」,是指客戶把錢存銀行,DCFlag = '借記'表示客戶從銀行取款。

我想從交易記錄中找到一些客戶,如果客戶在銀行存了一些錢,並且在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 
01需求和結果之間的差異

原因TransactionNo = A000004,因爲它是DCFlag =「借」,我要的是一個客戶後,把錢存銀行,他不會收回他們的一半。 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 min.In的最後一個SQL完成後,我運行它超過30分鐘,並沒有得到任何結果(因爲真實的數據更大),我取消了它,認爲失敗了。

誰能幫幫我?

回答

0

你可以這樣做:SQL FIDDLE

;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 

您可以測試它

相關問題