2017-04-04 27 views
0

也許有人可以幫助我。我一直在嘗試創建一個查詢來總結一個項目的時間量低於閾值。我的數據是這樣的:SQL Server計算總時間低於閾值

enter image description here

我試圖發現NR列小於或等於5的閾值的最後日期。我的數據如下圖表中最好的可視化: enter image description here

一個的情況下,最後一點是上述5所以這不會給的值。 B在2017年2月8日等於或低於閾值,並且C永遠不在上面。在這種情況下,我會使用第一個系列賽(盤旋)。

我創建的代碼幾乎讓我得到答案。請注意,代碼中的最後一步是計算從低於閾值的點到低於閾值的最後一點的數據差異。例如在B中 - 這將是2017年2月8日至2017年2月28日期間的差異。

代碼是:

IF OBJECT_ID('tempdb.dbo.#TAB', 'U') IS NOT NULL 
    DROP TABLE #TAB; 

    CREATE TABLE #TAB (SL VARCHAR(5), NR FLOAT, Date Date) 
INSERT INTO #TAB VALUES 
('A', '10', '1/1/2017'), 
('A', '4', '1/15/2017'), 
('A', '12', '2/1/2017'), 
('A', '4', '2/7/2017'), 
('A', '3', '2/15/2017'), 
('A', '6', '2/28/2017'), 
('B', '10', '1/1/2017'), 
('B', '8' ,'1/15/2017'), 
('B', '7' ,'2/1/2017'), 
('B', '5', '2/7/2017'), 
('B', '4', '2/15/2017'), 
('B', '4' ,'2/28/2017'), 
('C', '4', '1/1/2017'), 
('C', '4', '1/15/2017'), 
('C', '3' ,'2/1/2017'), 
('C', '3', '2/7/2017'), 
('C', '3' ,'2/15/2017'), 
('C' ,'2', '2/28/2017') 





;WITH CTE1 AS(

    SELECT *, ROW_NUMBER() OVER (PARTITION BY SL ORDER BY Date) Rn_ix FROM [#TAB]) 
, 
CTE2 AS 

(
SELECT 
CTE1.SL, 
NR, 
CTE1.Date Max_Date 
FROM CTE1 INNER JOIN (SELECT MAX(Date) Date, SL FROM CTE1 GROUP BY SL) NEW ON CTE1.Date = NEW.Date AND CTE1.SL = NEW.SL 
) 
, 
CTE3 AS 
(
    SELECT 
    CTe1.SL, 
    MIN(Date) Sample_date_Max, 
    MAX(Rn_IX) as Max_Row_Number, 
    CTE2.Max_Date 
    FROM CTE1 INNER JOIN CTE2 ON CTE1.SL = CTE2.SL 
    WHERE CTE1.NR <= 5 
    GROUP BY CTE1.SL, CTE2.Max_Date 
) 
, 
CTE4 AS 
(
SELECT SL, MAX(Date) as SampleDate, MAX(Rn_ix) Rn_IX 
FROM CTE1 WHERE NR >5 GROUP BY SL 

), 


    CTE5 AS 
    (SELECT CTE1.SL, CTe1.Date, NR 
    FROM CTE4 
    INNER JOIN CTE1 ON CTE4.Rn_IX = CTE1.Rn_ix-1 

    and CTE4.SL = CTe1.SL) 

    SELECT 
    CTe2.SL, 
    DATEDIFF(WEEK, CTE5.Date, CTE2.Max_Date) as Weeks_Under, 
ISNULL(CTE5.NR, CTE2.NR) AS NumericResult 

    FROM CTE5 FULL OUTER JOIN CTE2 ON CTE2.SL = CTE5.SL 
    ORDER BY CTE2.SL 

這給了我以下結果:

enter image description here

B是正確的 - 它已經跌破5 3周和第一個結果值,它越過後是5. A是正確的 - 目前的價值低於5。它下降,但回到上面。數字結果是最新值 C不正確 - C始終低於5,我希望在數字結果中看到該系列的第一個值(本例中爲01/01/2017,本例中爲4),而在第類別下數週。

總之我想要最近一段時間低於或等於5和相應的數字結果。

輸出應該是這樣的:

enter image description here

我真的很感激有這方面的幫助。如果這個問題措辭不當,請事先道歉。

在此先感謝!

回答

1

所以,如果我理解查詢邏輯...

WeeksUnder或者是在開始日期和結束日期之間的周區別,如果它從來沒有超過閾值的差或在周間如果超過閾值,則在上述日期和結束日期之前。

如果數值結果當前高於閾值或者從未高於閾值或低於閾值的第一個NR,NumericResult可以是最新的NR。

在這種情況下,它只是一個建立這個邏輯到一個查詢像這樣的事情:

SELECT SL, 
     WeeksUnder = MAX(CASE WHEN LastDateAbove IS NULL THEN DATEDIFF(DAY, FirstDate, LastDate)/7 WHEN LastDateAbove != LastDate THEN DATEDIFF(DAY, LastDateAbove, LastDate)/7 END), 
     NumericResult = MAX(CASE WHEN [Date] = COALESCE(LastDateAbove, LastDate) THEN COALESCE(NextNR, NR) END) 
FROM 
(
    SELECT T.SL, 
      T.NR, 
      T.[Date], 
      C.LastDateAbove, 
      C.FirstDate, 
      C.LastDate, 
      NextNR = (SELECT TOP 1 NR FROM #TAB WHERE SL = T.SL AND [Date] > C.LastDateAbove ORDER BY [Date]) 
    FROM #TAB T 
    CROSS APPLY 
    (
     SELECT LastDateAbove = MAX(CASE WHEN NR > 5 THEN [Date] END), 
       FirstDate = MIN([Date]), 
       LastDate = MAX([Date]) 
     FROM #TAB 
     WHERE SL = T.SL 
    ) AS C 
) AS T 
GROUP BY SL; 
+0

驚人!謝謝。從來沒有想過使用交叉應用 - 這仍然讓我困惑了一下。感謝您的幫助 - 這是驚人的 - 效果很好 –