2011-06-25 31 views
1

我問過a question in April@Mikael幫我解決了這個問題。這個需求已經發生了變化,我無法搞清楚如何構建查詢。 表結構是在T-SQL中查找自上次交易(同一天或前一天)以來的利潤總和

 
SID Sdate     Profit Units 
1 7/26/2010 9:15:00 AM -37.5 -1  
1 7/26/2010 12:00:00 PM -125 -1  
1 7/26/2010 12:45:01 PM -12.5 -1  
1 7/26/2010 12:45:02 PM 0  0  
1 7/26/2010 12:45:03 PM -75  1  
1 7/26/2010 2:00:01 PM -12.5 1  
1 7/26/2010 2:00:02 PM 0  0  
1 7/26/2010 2:00:03 PM -125 -1  
1 7/26/2010 2:15:00 PM -50  -1 
1 7/27/2010 9:15:00 AM 25  -1  
1 7/27/2010 12:00:00 PM 196  -1  
1 7/27/2010 2:15:00 PM -12.5 -1 
1 7/28/2010 9:15:00 AM 425  -1  
1 7/28/2010 12:00:00 PM -125 -1  
1 7/28/2010 2:15:00 PM -12.5 -1 
1 7/29/2010 9:15:00 AM -37.5 -1  
1 7/29/2010 12:00:00 PM -90  -1  
1 7/29/2010 12:45:01 PM -12.5 -1  
1 7/29/2010 12:45:02 PM 0  0  
1 7/29/2010 12:45:03 PM -75  1  
1 7/29/2010 2:15:00 PM 23  1 

的計算是爲說明:

 
SID Sdate     Profit Units End-of-day-Profit Comments 
1 7/26/2010 9:15:00 AM -37.5 -1  
1 7/26/2010 12:00:00 PM -125 -1  
1 7/26/2010 12:45:01 PM -12.5 -1  
1 7/26/2010 12:45:02 PM 0  0  
1 7/26/2010 12:45:03 PM -75  1  
1 7/26/2010 2:00:01 PM -12.5 1  
1 7/26/2010 2:00:02 PM 0  0  
1 7/26/2010 2:00:03 PM -125 -1  
1 7/26/2010 2:15:00 PM -50  -1 -175 SUM of profit(row 9 to row 11) going back to 7/26/2010 2:00:02 PM 
1 7/27/2010 9:15:00 AM 25  -1  
1 7/27/2010 12:00:00 PM 196  -1  
1 7/27/2010 2:15:00 PM -12.5 -1 33.5 SUM of profit (row 9 to row 14) going back to 7/26/2010 2:00:02 PM 
1 7/28/2010 9:15:00 AM 425  -1  
1 7/28/2010 12:00:00 PM -125 -1  
1 7/28/2010 2:15:00 PM -12.5 -1 321  SUM of profit(row9 to row 17) going back to 7/26/2010 2:00:02 PM 
1 7/29/2010 9:15:00 AM -37.5 -1  
1 7/29/2010 12:00:00 PM -90  -1  
1 7/29/2010 12:45:01 PM -12.5 -1  
1 7/29/2010 12:45:02 PM 0  0  
1 7/29/2010 12:45:03 PM -75  1  
1 7/29/2010 2:15:00 PM 23  1 -52  SUM of profit(row 22 to row 23) going back to 7/29/2010 12:45:02 PM 

其結果將是

 
SID Sdate  Profit Units 
1 7/26/2010 -175 -1 
1 7/27/2010 33.5 -1 
1 7/28/2010 321  -1 
1 7/29/2010 -52  1 

淨利潤列的總和在每天下午2:15取爲每個SID。爲簡單起見,我包含了一個SID。想法是回顧當前日期或前幾天的利潤= 0和單位= 0的行。一旦找到該行,然後總結所有利潤值。

我感謝這方面的任何幫助。謝謝。

+0

'淨利潤列的總和被以2:每天15PM - 如何?我的意思是,它是(應該是)手動完成還是使用代理作業?在你的例子中,每天下午2:15有一行,它也包含一個Profit值。如果沒有這麼一排呢?爲了增加另一個每日利潤日期值,應該插入時間爲2:15 PM,利潤爲0,或者腳本是否應該使用Profit搜索最新的行並存儲End-那裏的日常利潤? –

+0

Sdate是一個具有唯一約束的列嗎?數據如何插入?您是否首先插入Sdate M/dd/yyyy 2:15:00 PM的記錄,然後計算每日收益? – boes

+0

@Frans,sdate不是具有唯一約束的列。由m/dd/yyyy 2:15 PM指示的日結束記錄將在運行過程生成這些記錄時存儲在表中。 – ARK

回答

1

我無權訪問數據庫來測試它。但是填充一個表變量@t然後試試這個。

declare @t table (SID int, Sdate datetime, profit decimal(9,1), units int) 

<populate it> 

我猜你想要爲每個SID列表。我誤解了這一點。我喜歡改變我的答案。

select SID, Sdata, (select sum(Profit) from @t where Sdate between s.start and s.Sdate and S.SID = SID) profit, Units from 
(select SID, Sdata, (select max(Sdata) from @t where profit = 0 and unit = 0 and Sdata < t.Sdate and SID = t.SID) start from @t t 
where DATEPART(MINUTE, t.Sdata) =15 AND DATEPART(HOUR, t.Sdata) = 14 AND DATEPART(SECOND, t.Sdata) = 0) s 
ORDER BY SID, Sdate 
+0

您的查詢產生所需的結果。在我宣佈它作爲答案之前,我想仔細檢查結果不僅僅是這一個SID。非常感謝您的回覆。 – ARK

+0

我剛剛完成驗證結果。查詢工作正常。感謝您的幫助。 – ARK

1

DDL &樣本數據:

CREATE TABLE atable (
    SID int, 
    Sdate datetime, 
    Profit money, 
    Units int 
); 
INSERT INTO atable (SID, Sdate, Profit, Units) 
SELECT 1, '7/26/2010 9:15:00 AM' , -37.5, -1 UNION ALL  
SELECT 1, '7/26/2010 12:00:00 PM', -125 , -1 UNION ALL  
SELECT 1, '7/26/2010 12:45:01 PM', -12.5, -1 UNION ALL  
SELECT 1, '7/26/2010 12:45:02 PM', 0 , 0 UNION ALL  
SELECT 1, '7/26/2010 12:45:03 PM', -75 , 1 UNION ALL  
SELECT 1, '7/26/2010 2:00:01 PM' , -12.5, 1 UNION ALL  
SELECT 1, '7/26/2010 2:00:02 PM' , 0 , 0 UNION ALL  
SELECT 1, '7/26/2010 2:00:03 PM' , -125 , -1 UNION ALL  
SELECT 1, '7/26/2010 2:15:00 PM' , -50 , -1 UNION ALL 
SELECT 1, '7/27/2010 9:15:00 AM' , 25 , -1 UNION ALL  
SELECT 1, '7/27/2010 12:00:00 PM', 196 , -1 UNION ALL  
SELECT 1, '7/27/2010 2:15:00 PM' , -12.5, -1 UNION ALL 
SELECT 1, '7/28/2010 9:15:00 AM' , 425 , -1 UNION ALL  
SELECT 1, '7/28/2010 12:00:00 PM', -125 , -1 UNION ALL  
SELECT 1, '7/28/2010 2:15:00 PM' , -12.5, -1 UNION ALL 
SELECT 1, '7/29/2010 9:15:00 AM' , -37.5, -1 UNION ALL  
SELECT 1, '7/29/2010 12:00:00 PM', -90 , -1 UNION ALL  
SELECT 1, '7/29/2010 12:45:01 PM', -12.5, -1 UNION ALL  
SELECT 1, '7/29/2010 12:45:02 PM', 0 , 0 UNION ALL  
SELECT 1, '7/29/2010 12:45:03 PM', -75 , 1 UNION ALL  
SELECT 1, '7/29/2010 2:15:00 PM' , 23 , 1; 

查詢:

WITH ranges AS (
    SELECT 
    t.SID, 
    t.Sdate, 
    t.Units, 
    SdateStart = MAX(t0.Sdate) 
    FROM atable t 
    INNER JOIN atable t0 
     ON t0.SID = t.SID AND t0.Sdate < t.Sdate 
     AND t0.Profit = 0 AND t0.Units = 0 
    WHERE DATEPART(HH, t.Sdate) = 14 
    AND DATEPART(MI, t.Sdate) = 15 
    GROUP BY 
    t.SID, 
    t.Sdate, 
    t.Units 
) 
SElECT 
    r.SID, 
    r.Sdate, 
    Profit = SUM(t.Profit), 
    r.Units 
FROM ranges r 
    INNER JOIN atable t ON t.SID = r.SID 
    AND t.Sdate BETWEEN r.SdateStart AND r.Sdate 
GROUP BY 
    r.SID, 
    r.Sdate, 
    r.Units; 

輸出:

SID   Sdate     Profit    Units 
----------- ----------------------- --------------------- ----------- 
1   2010-07-26 14:15:00.000 -175.00    -1 
1   2010-07-27 14:15:00.000 33.50     -1 
1   2010-07-28 14:15:00.000 321.00    -1 
1   2010-07-29 14:15:00.000 -52.00    1 
+0

@Andriy M,我嘗試在「範圍」cte內使用標準SID = 1過濾數據,同時嘗試對數據庫運行此查詢。它返回空的結果。我不知道爲什麼。 – ARK

+0

@Andriy M,別介意。我沒有刷新頁面。我剛剛運行修改後的查詢。它執行得很好。謝謝你的幫助。對於它的價值,cte似乎比子查詢版本運行得更快。 =) – ARK

+0

是不是我的版本中排序造成的性能差異? –