2017-05-21 8 views
0

私は、2つのパラメータの事前状態とステータスを取得するクエリを作成しようとしています。ここから私は期間を要約したいと思う。 これが私のテーブルです:2行目から7行目の合計

Title_Id Media_Info_Id Rank     Title_Pre_Status_Name        Title_Status_Name         duration Activity_Date 
----------- ------------- -------------------- -------------------------------------------------- -------------------------------------------------- ----------- ------------- 
49090  -1   1     New Work Order          Annotate WO          0   2016-11-15 
49090  -1   2     Annotate WO          New Work Order          69309  2017-01-02 
49090  -1   3     New Work Order          Annotate WO          1   2017-01-02 
49090  -1   4     Annotate WO          Ingest WO           4   2017-01-02 
49090  -1   5     Ingest WO           QC WO            1353  2017-01-03 
49090  -1   6     QC WO            New Work Order          33390  2017-01-26 
49090  -1   7     New Work Order          Annotate WO          971   2017-01-27 
49090  -1   8     Annotate WO          Ingest WO           27665  2017-02-15 

ので、例えば、私は、PUTのように取得しています:

前の状態= '注釈WO' とステータス= '新しい作業指示'

私がすべき行2-7の合計を戻します。 あまりにも多くの内側の選択なしでこれを行うための良い方法の任意のアイデアがありますか?

+1

ロジックが行2-7を選択することで、あなたの前と状況の結果は何である:

select sum(duration) from mytable where rank between (select min(rank) from mytable where title_status_name = @prestatus) and (select max(rank) from mytable where title_status_name = @status); 

クエリが高速に実行するためには、これらのインデックスを持っている必要がありますか? –

+0

はユーザーの入力ではなく、彼が望む開始状態と終了状態を選択することができます。同じ状態でいくつかの変更がある場合は、ロジックは最小\最大を取る –

+0

これはどのバージョンのSQL Serverですか? –

答えて

0

私はこのようにそれを行うにはうまく管理:

SELECT 
    t.Title_Id, 
    sum(duration) as duration, 
    date = (select min(Activity_Date) from Dwh_Fact_Title_Activity_Ranks_V t1 where t.Title_Id = t1.Title_Id and t1.Title_Pre_Status_Name = @pre_Statuse) 
FROM Dalet_DWH.dbo.Dwh_Fact_Title_Activity_Ranks_V t 
where 
t.Rank>=(select 
      min(t2.Rank) 
     from Dalet_DWH.dbo.Dwh_Fact_Title_Activity_Ranks_V t2 
     where 
      t.title_id = t2.Title_Id 
      and 
      t2.Title_Pre_Status_Name = @pre_Statuse) 
and 
t.Rank<=(select 
      max(t2.Rank) 
     from Dalet_DWH.dbo.Dwh_Fact_Title_Activity_Ranks_V t2 
     where 
      t.title_id = t2.Title_Id 
      and 
      t2.Title_Status_Name = @status) 
group by t.Title_Id 

それは動作しますが、私は、実行時間があると思います長いです。

お気軽にアルゴリズムを改善してください。

おかげで、すべての

0

私が正しくあなたのロジックを理解している場合、このような何かが動作するはずです:

select t.* 
from t 
where t.rank >= (select min(t2.rank) from t t2 where t2.title_id = t.title_id and t2.Title_Pre_Status_Name = 'Annotate WO') and 
     t.rank <= (select max(t2.rank) from t t2 where t2.title_id = t.title_id and t2.Title_Pre_Status_Name = 'New Work Order'); 
+0

です。私は何の入力が得られるのか分かりません –

+0

これはひどい考えです。クエリのコストは、各行が終了すると述語句が起動されるため、行数とともに増加します。 –

+0

@clifton_h。 。 。このクエリは問題ありません。おそらく 't(title、title_pre_status_name、rank)'のインデックスを持つ最も最適化されたソリューションです。 –

1

あなたが与えられた状態の最大IDまで与えられた前の状態の最小IDからすべてのレコードをしたいです。したがって、最小IDを見つける。最大IDを見つける。レコードを取得します。

create index idx1 on mytable(title_status_name, rank); -- finds min and max rank for 
                 -- a status quickly 

create index idx2 on mytable(rank, duration); -- finds the records based on rank quickly 
               -- and contains the duration to add up 
関連する問題