簡體   English   中英

SQL Server:查找大於 5 的最近連續記錄

[英]SQL Server : find recent consecutive records that are greater than 5

我需要編寫一個查詢,顯示結果通過分解FormID有基於最新的值大於5 LogDate

根據最新的LogDate ,如果有一個小於 5 的值,它應該顯示從那個點開始的大於 5 的值,因為如果您願意,小於 5 的值是“重置”。

我基本上是在查看最近連續的大於 5 的LogDate記錄。

假設我們有以下記錄集:

FormID   Value  LogDate    
--------------------------
Form2    6      10/12/19   
Form2    7      10/13/19   
Form1    8      10/12/19
Form1    12     10/12/19
Form1    3      10/14/19
Form1    8      10/15/19
Form1    6      10/21/19  

以下將返回以下內容(請注意,我也喜歡顯示 row_num:

 FormID   Value  LogDate   row_num
 ----------------------------------
 Form2    6      10/12/19  1
 Form2    7      10/13/19  2
 Form1    8      10/15/19  1
 Form1    6      10/21/19  2

請注意,在上面的示例中,由於以下記錄的最近值低於 5(值為 3),因此我們需要獲取高於 5 的記錄。

另一個例子:

FormID   Value  LogDate     
Form1    8      10/15/19
Form1    3      10/21/19  

結果:不會顯示任何結果,因為在最近的記錄中有大於 5

另一個例子:

FormID   Value  LogDate    
Form2    4      10/12/19   
Form2    3      10/13/19   
Form1    16     10/12/19
Form1    3      10/12/19
Form1    3      10/14/19
Form1    8      10/15/19
Form1    12     10/21/19 

這里的結果是:

FormID   Value  LogDate   row_num
Form1    8      10/15/19  1
Form1    12     10/21/19  2

另一個例子:

FormID   Value  LogDate    
Form1    12      10/12/19   
Form2    13      10/13/19  

結果:

FormID   Value  LogDate    row_num
Form1    12      10/12/19  1 
Form2    13      10/13/19  2

根據我的理解,這可以通過 LAG 函數來完成,但不確定如何完全放置。

我們可以執行以下操作:

   DECLARE @mytable TABLE
   (
     FormID VARCHAR(50), 
     [Value] INT, 
     LogDate DATETIME
    )

    select t.*, 
        lag(value) over(partition by formid order by logdate) lag_value
    from @mytablet

但不知道如何把它拉在一起。

如果我正確地跟隨你,你可以用這樣的窗口函數來做到這一點:

select 
from (
    select t.*, 
        row_number() over(partition by formid order by logdate desc) rn,
        sum(case when value > 5 then 1 else 0 end) over(partition by formid order by logdate desc) grp
    from mytable t
) t
where rn = grp

這個想法是將大於5的值與行號進行比較,從最近的值開始計數。 可以保留兩個值相等的行。

一種方法是:

select t.*,
       row_number() over (partition by formid order by logdate)
from t
where t.logdate > (select coalesce(max(t.logdate), '2000-01-01')
                   from t t2
                   where t2.formid = t.formid and t.value <= 5
                  );

您還可以使用窗口函數:

select t.*,
       row_number() over (partition by formid order by logdate)
from (select t.*,
             max(case when value <= 5 then logdate end) over (partition by formid) as logdate_5
      from t
     ) t
where logdate_5 is null or
      date > logdate_5
order by formid, logdate;

fiddle 中找到指示性答案。

reset_calendar是重置發生的日期,用於過濾數據。

SELECT temp.*,
       ROW_NUMBER() OVER (PARTITION BY temp.FormID ORDER BY temp.LogDate) AS Sequence
FROM (
  SELECT t.*
  FROM t
  LEFT JOIN (
    SELECT FormID, MAX(LogDate) AS recent_reset 
    FROM t
    WHERE Value<6
    GROUP BY FormID) AS reset_calendar
  ON t.FormID = reset_calendar.FormID
  WHERE t.LogDate > reset_calendar.recent_reset OR reset_calendar.recent_reset IS NULL)temp

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM