2017-03-09 51 views
0

我是SQL Server(2012)的新手,但我被分配了必須使用它的項目。 數據庫由一個表(單位:百萬行計),這看起來主要是這樣的:SQL查詢 - 設計鬥爭

Number (float) Date (datetime) Status (nvarchar(255)) 
999    2016-01-01 14:00:00.000 Error 
999    2016-01-02 14:00:00.000 Error 
999    2016-01-03 14:00:00.000 Ok 
999    2016-01-04 14:00:00.000 Error 
888    2016-01-01 14:00:00.000 Error 
888    2016-01-02 14:00:00.000 Ok 
888    2016-01-03 14:00:00.000 Error 
888    2016-01-04 14:00:00.000 Error 
777    2016-01-01 14:00:00.000 Error 
777    2016-01-02 14:00:00.000 Error 

我要創建一個查詢,它會顯示我只有電話號碼(每行一個號碼,這樣大概集團通過符合條件的號碼):

  1. 號碼再次出現至少3次
  2. 前兩次(即必須基於日期;原本記錄不按日期排序)必須是一個錯誤

例如,在上表中,符合條件的電話號碼只有888,因此999的第二個最新狀態爲「確定」,而777號碼僅再次出現2次。

我會很感激任何幫助!

在此先感謝!

回答

1
select *, ROW_NUMBER() OVER(partition by Number, order by date desc) as times 

FROM 

(

    select Number, Date 
    From table 
    where Number in 
    ( 
     select Number 
     from table 
     group by Number 
     having count (*) >3 
) as ABC 

WHERE ABC.times in (1,2) and ABC.Status = 'Error' 
4

您可以使用row_number()和有條件聚集:

select number 
from (select t.*, 
      row_number() over (partition by number order by date desc) as seqnum 
     from t 
    ) t 
group by number 
having count(*) >= 3 and 
     max(case when seqnum = 1 then status end) = 'Error' and 
     max(case when seqnum = 2 then status end) = 'Error'; 

注:float是一個非常,非常糟糕的類型,使用的 「號碼」 一欄。特別是,兩個數字可能看起來相同,但在低位中有所不同。他們將在group by中產生不同的行。

您應該使用varchar()作爲電話號碼。這給你最大的靈活性。如果您需要將號碼存儲爲號碼,則decimal/numeric是比float更好的選擇。

+0

嗨,戈登,謝謝你的回答,它的作用就像一個魅力! –

1
with CTE as 
(
select t1.*, row_number() over(partition by t1.Number order by t1.date desc) as r_ord 
from MyTable t1 
) 
select C1.* 
from CTE C1 
inner join 
(
select Number 
from CTE 
group by Number 
having max(r_ord) >=3 
) C2 
on C1.Number = C2.Number 
where C1.r_ord in (1,2) 
and C1.Status = 'Error'