2017-03-09 8 views
0

私はかなり新しいSQL Server(2012)ですが、私はそれを使用する必要があるプロジェクトに割り当てられました。 データベースは、主に次のようになります(数百万行でカウント)1台で構成されています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つの番号を私の唯一の電話番号が表示されますクエリを作成する必要があります数)の条件を満たしています。

  1. 数は、少なくとも3回
  2. 最後の2回は、(その日付に基づいてする必要が再び表示されます。もともとレコードが日付でソートされていません)エラー
  3. なければなりません?

たとえば、上記の表では、条件を満たす電話番号は888であり、999は第2の最新ステータスであり、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は、 "番号" 欄に使用する、本当に、本当に悪いタイプです。特に、2つの数字は同じように見えますが、下位ビットが異なります。彼らは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'