2017-08-04 42 views
0

我需要找到每個用戶在'失敗'時具有特定狀態的最新3條記錄。起初看起來很簡單,但我似乎無法做到。找到相同狀態的最新3條記錄

所以在一個表:

ID   Date   Status 
1   2017-01-01  Fail 
1   2017-01-02  Fail 
1   2017-02-04  Fail 
1   2015-03-21  Pass 
1   2014-02-19  Fail 
1   2016-10-23  Pass 
2   2017-01-01  Fail 
2   2017-01-02  Pass 
2   2017-02-04  Fail 
2   2016-10-23  Fail 

我希望ID 1返回爲最近3個記錄是失敗的,但不是ID 2,因爲他們有內他們的三個失敗的通行證。每個用戶可能有任何數量的通過和失敗記錄。有成千上萬個不同的ID

到目前爲止,我已經嘗試了使用ROW_NUMBER()命令進行嘗試的CTE,但無法想出一種方法來確保最新的三個結果都具有相同的Fail狀態。

預期結果

ID Latest Fail Date Count 
1 2017-02-04   3 
+0

向我們展示您的查詢的嘗試! – jarlh

+1

你可以添加預期的結果fot它 –

+0

@jarlh查詢嘗試不起作用,所以沒有多少點顯示它 - 我做了幾次嘗試,所以我不只是尋找一個簡單的答案放心。 – bhs

回答

2

也許嘗試這樣的事:

WITH cte 
AS 
(

SELECT id, 
     date, 
     status, 
     ROW_NUMBER() OVER (PARTITION BY id ORDER BY date DESC) row 
FROM #table 


),cte2 
AS 
(

SELECT id, max(date) as date, count(*) AS count 
FROM cte 
WHERE status = 'fail' 
AND row <= 3 
GROUP BY id 
) 

SELECT id, 
     date AS latest_fail, 
     count 
FROM cte2 
WHERE count = 3 
+0

只是測試這個,我敢肯定它工作正常 - 謝謝:-) – bhs

+0

不用擔心隊友:) – VDK

0

檢查。

演示:Here

with CTE as 
(
select *,ROW_NUMBER() over(partition by id order by date desc) rnk 
from temp 
where Status ='Fail' 
) 
select top 1 ID,max(DATE) as Latest_Fail_Date ,COUNT(rnk) as count 
from CTE where rnk <=3 
group by ID 

Ouptut:

enter image description here

+0

這很好,但有成千上萬的ID,每一個都有他們的Pass.Fails的歷史等我需要一個查詢給我一個所有ID匹配的列表匹配該模式。我編輯了這個問題,因爲之前並不清楚。 – bhs

+0

@bhs我不能得到你想要的。?哪個pattenr?ID是用戶ID? –

+0

一個匹配三個最新失敗記錄模式的所有ID的列表 – bhs

0

我想你可以使用cross apply做到這一點:

select i.id 
from (select distinct id from t) i cross apply 
    (select sum(case when t.status = 'Fail' then 1 else 0 end) as numFails 
     from (select top 3 t.* 
      from t 
      where t.id = i.id 
      order by date desc 
      ) ti 
    ) ti 
where numFails = 3; 

注意:你可能有一個表的所有ID。如果是這樣,你使用它而不是select distinct子查詢。

,或類似:

select i.id 
from (select distinct id from t) i cross apply 
    (select top 3 t.* 
     from t 
     where t.id = i.id 
     order by date desc 
    ) ti 
group by i.id 
having min(ti.status) = 'Fail' and max(ti.status) = 'Fail' and 
     count(*) = 3; 
0

在這裏你去:

declare @numOfTries int = 3; 

with fails_nums as 
(
     select *, row_number() over (partition by ID order by [Date] desc) as rn 
     from #fails 
) 
select ID, max([Date]) [Date], count(*) as [count] 
from fails_nums fn1 
where fn1.rn <= @numOftries 
group by ID 
having count(case when [Status]='Fail' then [Status] end) = @numOfTries 

Example here

+0

我喜歡這樣,因爲它很優雅,很容易閱讀(我以前沒有用過),但它不起作用。如果有一個失敗的單行也會被返回。 – bhs

+0

我的壞=(更正了查詢 –

相關問題