2010-07-10 58 views
0

我很想知道我的查詢的正確性如何發佈問題here。,我懷疑如果我寫了一個完美的問題,並且我想問問大家哪裏可以改進我的代碼。查詢的正確性

注:我不想用很多代碼填充這個地方,很簡短。謝謝。

SELECT a.BookingId       AS BookingId, 
     CAST(b.TransactionDateTime AS DATE) AS TransactionDate 
FROM TC33_AuditTrial A 
     JOIN TC33_AuditTrial b 
     ON  a.AuditId     = b.AuditId 
WHERE a.TransactionType     = 'S' 
AND CAST(a.TransactionDateTime AS DATE) = 
     (SELECT CAST(b.TransactionDateTime AS DATE) 
     FROM TC33_AuditTrial b 
     WHERE b.BookingId = a.BookingId 
     AND  b.AuditId = 
       (SELECT MAX(b.AuditId) 
       FROM TC33_AuditTrial b 
       WHERE a.BookingId  = b.BookingId 
       AND  b.TransactionType = 'R' 
       ) 
     ) 
AND a.TransactionValue = 
     (SELECT SUM(b.TransactionValue) 
     FROM TC33_AuditTrial b 
     WHERE a.BookingId  = b.BookingId 
     AND  b.TransactionType = 'R' 
     ) 
+0

我認爲你會有更好的結果在該網站論壇上提出這個問題:http://beyondrelational.com/groups/tsqlchallenge/forum/t/2208.aspx – krock 2010-07-10 05:32:22

+0

是的,我做了謝謝,我的意圖不是垃圾郵件我很感興趣知道我可以做得更好。 – Chaitanya 2010-07-10 05:37:32

回答

3

未刪除

我原來的答覆是

SELECT BookingId, CONVERT(VARCHAR(8), TransactionDateTime, 112) AS TransactionDate 
FROM TC33_AuditTrial 
GROUP BY BookingId, CONVERT(VARCHAR(8), TransactionDateTime, 112) 
HAVING 
SUM(CASE TransactionType WHEN 'S' THEN TransactionValue END) <= 
SUM(CASE TransactionType WHEN 'R' THEN TransactionValue END) 
ORDER BY BookingID 

這讓我很高興,因爲它只是把一次通過數據。

然後我注意到規範的更新位,它必須限制在包含該預訂條目的第一個日期。我能想到做到這一點的唯一方法是添加一個子查詢,從而顯着增加了查詢的成本。

令人沮喪的方面是,雖然我想結果限制爲每個BookingId的第一天,我已經通過BookingId,日編組

感覺就像有可能會得到這個限制沒有一些聰明的辦法子查詢,但如果是的話,迄今爲止它已經躲過了我!

我剛剛設法讓'OVER'工作。我不會公佈這個答案,直到比賽被關閉後,除了它具有完全相同的查詢計劃的發表8KB

WITH X AS 
(
SELECT BookingId, 
     RANK() OVER(PARTITION BY BookingId ORDER BY CONVERT(VARCHAR(8), TransactionDateTime, 112)) AS Rnk, 
     CONVERT(VARCHAR(8), TransactionDateTime, 112) AS TransactionDate, 
     SUM(CASE TransactionType WHEN 'S' THEN TransactionValue END) AS S, 
     SUM(CASE TransactionType WHEN 'R' THEN TransactionValue END) AS R 
FROM  TC33_AuditTrial t1 
GROUP BY BookingId, 
     CONVERT(VARCHAR(8), TransactionDateTime, 112) 
) 

SELECT BookingId, TransactionDate 
FROM X 
WHERE Rnk = 1 AND S<=R 
ORDER BY BookingID 
+0

+1:希望我能想到它。 – 2010-07-10 21:49:29

+0

@OMG Shame沒有像'AND PARTITION_NUMBER(CONVERT(VARCHAR(8),TransactionDateTime,112))= 1'這樣的語法! – 2010-07-10 22:17:07

+0

謝謝你,我從來沒有想過這個查詢可以用簡單的語言寫成。 – Chaitanya 2010-07-10 22:22:42

1

了一個曾在太跳...

SELECT 
    BookingID, 
    CONVERT(VARCHAR(8), TransactionDateTime, 112) AS TransactionDate 
FROM (
SELECT 
    BookingID, 
    TransactionDateTime, 
    COALESCE(pvt.S,0) AS Sale, 
    COALESCE(pvt.R,0) AS Receipt, 
    ROW_NUMBER() OVER (
    PARTITION BY BookingID ORDER BY (TransactionDateTime)) AS Rn 
FROM (
    SELECT 
    BookingID, 
    DATEADD(DD, DATEDIFF(DD,0,TransactionDateTime), 0) AS TransactionDateTime, 
    TransactionType, 
    TransactionValue 
    FROM TC33_AuditTrial 
) t 
PIVOT (
    SUM(TransactionValue) 
    FOR TransactionType IN (S,R) 
) AS pvt 
) t2 
WHERE Receipt >= Sale 
AND Rn = 1 
+0

+1。感到驚訝的是我們2個答案的執行計劃有多相似。 – 2010-07-10 23:11:47

+0

預先比較IO統計數據可怕嗎?沒有區別。但不想發佈,如果它被吹出水... – 8kb 2010-07-10 23:15:55

+0

我認爲那裏基本上沒有區別。唯一有點奇怪的是,即使當我將它們放在存儲過程中的長度名稱相同時,出於某種原因,我發現根據Management Studio中的客戶端統計信息,您始終會從服務器發回13%多的字節。 – 2010-07-10 23:41:21