2017-05-05 27 views
0

私が使用しているデータベースでは、一意のIDで最新の番号を選択する素晴らしい方法はありません。私たちは、元のテーブルに戻ってくる一連のサブクエリを使って、最新のレコードを取得するために絞り込む必要があります。元のテーブルはTBL_POLです。 Ex。最新のレコードを選択する最良の方法

Policy_ID Load_DATE ENDORSEMENT# SEQUENCE EXTRACTDATE 
25276  8/16/2015  0    1  8/15/2015  
25276  2/13/2016  1    2  2/12/2016 
25276  9/24/2016  3    4  9/20/2016 
25276  9/24/2016  3    4  9/20/2016 
25276  9/24/2016  2    3  9/20/2016 

ので最初、我々は最大負荷の日付を取得し、元のテーブルに戻って参加し、その後、最大承認番号を取得し、再度参加し、最大のシーケンスを取得し、再度参加し、最終的に最大のエキスの日付を取得します独特のものになるように最終的な記録に戻ってください。上記は一例です。

これを行う簡単な方法はありますか?誰かが(partition by)を介してrow_number()を説明しましたが、あなたが好きな行番号を返します。私は一回のスワイプで上記のすべての属性を持つレコードをすばやく取得するための方法です。これらのクエリは少し時間がかかりますので、これを行う方がいいですか?

おかげ

+0

は、あなたがサンプルデータに基づいて予想される結果を投稿できるフィードバックが、結果とパフォーマンス? –

+0

テーブルのスキーマを変更して列/トリガを追加するオプションがありますか? –

+0

「TOP 1」のようなものをお探しですか?例えば'SELECT TOP 1 *からTBL_POL ORDER BY Load_Date DESC、[ENDORSEMENT#] DESC、SEQUENCE DESC、EXTRACTDATE DESC'から?注:クエリの実行に時間がかかる場合は、少なくともLoad_DATE列にインデックスを置く必要があります(または、使用する必要があるすべての列をカバーする方が良い)。 – ZLK

答えて

1

@Bryant、

まず、@Backsはあなたのために、この記事を救いました。私が最初にそれを見たとき、私は "だと思った。彼はいつでも彼の要求を読みやすくするために気にしないなら、なぜを気にするべきだろう?さらに、コード化されたサンプルを探している場合は、簡単に消耗しているテストデータを作成して、皆さんが手助けをしやすくなるようにしてください。また、@ Felix Pamittanが示唆しているように、あなたの期待リターンは何であるべきかを投稿するべきです。

すぐに消耗しやすいテストデータを投稿する方法の1つです。また、別のPolicy_IDを追加して、1つのPolicy_IDではなくテーブル全体に対してこれを行う方法をデモンストレーションできるようにしました。

--===== If the test table doesn't already exist, drop it to make reruns in SSMS easier. 
    -- This is NOT a part of the solution. We're just simulating the original table 
    -- using a Temp Table. 
    IF OBJECT_ID('tempdb..#TBL_POL','U') IS NOT NULL 
    DROP TABLE #TBL_POL 
; 
--===== Create the test table (technically, a heap because no clustered index) 
    -- Total SWAG on the data-types because you didn't provide those, either. 
CREATE TABLE #TBL_POL 
     (
     Policy_ID  INT  NOT NULL 
     ,Load_DATE  DATE NOT NULL 
     ,ENDORSEMENT# TINYINT NOT NULL 
     ,SEQUENCE  TINYINT NOT NULL 
     ,EXTRACTDATE DATE NOT NULL 
     ) 
; 
--===== Populate the test table 
INSERT INTO #TBL_POL 
     (Policy_ID,Load_DATE,ENDORSEMENT#,SEQUENCE,EXTRACTDATE) 
SELECT Policy_ID,Load_DATE,ENDORSEMENT#,SEQUENCE,EXTRACTDATE 
    FROM (VALUES 
     --===== Original values provided 
     (25276,'8/16/2015',0,1,'8/15/2015') 
     ,(25276,'2/13/2016',1,2,'2/12/2016') 
     ,(25276,'9/24/2016',3,4,'9/20/2016') 
     ,(25276,'9/24/2016',3,4,'9/20/2016') 
     ,(25276,'9/24/2016',2,3,'9/20/2016') 
     --===== Additional values to demo multiple Policy_IDs with 
     ,(12345,'8/16/2015',0,1,'8/15/2015') 
     ,(12345,'9/24/2016',1,5,'2/12/2016') 
     ,(12345,'2/13/2016',1,2,'2/12/2016') 
     ,(12345,'9/24/2016',3,4,'9/20/2016') 
     ,(12345,'9/24/2016',3,4,'9/20/2016') 
     ,(12345,'9/24/2016',2,3,'9/20/2016') 

     ) v (Policy_ID,Load_DATE,ENDORSEMENT#,SEQUENCE,EXTRACTDATE) 
; 
--===== Show what's in the test table 
SELECT * 
    FROM #TBL_POL 
; 

一度に複数のPolicy_IDについて質問を解決したい場合は、次のように動作します。

--===== Use a partitioned windowing function to find the latest row 
    -- for each Policy_ID, ignoring "dupes" in the process. 
    -- This assumes that the "sequence" column is king of the hill. 
    WITH cteEnumerate AS 
     (
     SELECT * 
       ,RN = ROW_NUMBER() OVER (PARTITION BY Policy_ID ORDER BY SEQUENCE DESC) 
      FROM #TBL_POL 
     ) 
SELECT Policy_ID,Load_DATE,ENDORSEMENT#,SEQUENCE,EXTRACTDATE 
    FROM cteEnumerate 
    WHERE RN = 1 
; 

あなたがこれだけのために1 Policy_IDを探しているなら、提案@ZLK「TOP 1」の方法は動作しますが、これ以上にWHERE句を追加します。より速く動作するかどうかは不明ですが、同じインデックスが両方を助けます。ここでは、WHERE句(パラメータ化可能)を使用したソリューションがあります。

--===== Use a partitioned windowing function to find the latest row 
    -- for each Policy_ID, ignoring "dupes" in the process. 
    -- This assumes that the "sequence" column is king of the hill. 
    WITH cteEnumerate AS 
     (
     SELECT * 
       ,RN = ROW_NUMBER() OVER (PARTITION BY Policy_ID ORDER BY SEQUENCE DESC) 
      FROM #TBL_POL 
      WHERE Policy_ID = 25276 
     ) 
SELECT Policy_ID,Load_DATE,ENDORSEMENT#,SEQUENCE,EXTRACTDATE 
    FROM cteEnumerate 
    WHERE RN = 1 
; 
0

を使用すると、別のサンプルデータを投げるグルーピングSET

を試してみてください可能性があります。 また、パフォーマンスについてはわかりません。

両方

SELECT * 
FROM (
    SELECT Policy_ID 
     ,max(Load_DATE) Load_DATE 
     ,max(ENDORSEMENT#) ENDORSEMENT# 
     ,max(SEQUENCE) SEQUENCE 
     ,max(EXTRACTDATE) EXTRACTDATE 
    FROM #TBL_POL t 
    GROUP BY grouping SETS(Policy_ID, Load_DATE, ENDORSEMENT#, SEQUENCE, EXTRACTDATE) 
    ) t4 
WHERE Policy_ID IS NOT NULL 

    drop table #TBL_POL 
関連する問題