2017-04-20 12 views
5

サブグループ内で正しいランクを取得しようとしており、結果に問題があります。タイムスタンプに基づいてグループが変更されるたびにランクを取得する必要があります。(サブ)グループ内のOracleランク()

たとえば、このテーブルを使用した:

create table syntrans (
    transid  number, 
    launchtime timestamp, 
    status  varchar2(10) 
); 

insert into syntrans values (1, '19-APR-17 07.34.05.824875 PM','FAIL'); 
insert into syntrans values ( 1, '19-APR-17 07.34.06.828753 PM','FAIL'); 
insert into syntrans values ( 1, '19-APR-17 07.34.08.567579 PM','SUCCESS'); 
insert into syntrans values ( 1, '19-APR-17 08.07.31.731745 PM','SUCCESS'); 
insert into syntrans values ( 1, '19-APR-17 08.07.32.735582 PM','SUCCESS'); 
insert into syntrans values ( 2, '19-APR-17 08.17.51.332804 PM','FAIL'); 
insert into syntrans values ( 2, '19-APR-17 08.17.52.336530 PM','FAIL'); 
insert into syntrans values ( 2, '19-APR-17 08.19.27.993327 PM','SUCCESS'); 
insert into syntrans values ( 2, '19-APR-17 08.25.54.860077 PM','FAIL'); 
insert into syntrans values ( 2, '19-APR-17 08.25.55.862830 PM','SUCCESS'); 

を私は現在取得していますどのようなことは必要とされている出力はこのようなものです

SELECT transid, 
     launchtime, 
     status, 
     rank() over (partition by status order by launchtime) rnk 
    FROM syntrans 
order by transid, launchtime, status; 

    TRANSID LAUNCHTIME      STATUS   RNK 
---------- ------------------------------ ---------- ---------- 
     1 19-APR-17 07.34.05.824875 PM FAIL    1 
     1 19-APR-17 07.34.06.828753 PM FAIL    2 
     1 19-APR-17 07.34.08.567579 PM SUCCESS    1 
     1 19-APR-17 08.07.31.731745 PM SUCCESS    2 
     1 19-APR-17 08.07.32.735582 PM SUCCESS    3 
     2 19-APR-17 08.17.51.332804 PM FAIL    3 
     2 19-APR-17 08.17.52.336530 PM FAIL    4 
     2 19-APR-17 08.19.27.993327 PM SUCCESS    4 
     2 19-APR-17 08.25.54.860077 PM FAIL    5 
     2 19-APR-17 08.25.55.862830 PM SUCCESS    5 

です:

TRANSID LAUNCHTIME      STATUS   RNK 
---------- ------------------------------ ---------- ---------- 
     1 19-APR-17 07.34.05.824875 PM FAIL    1 
     1 19-APR-17 07.34.06.828753 PM FAIL    2 
     1 19-APR-17 07.34.08.567579 PM SUCCESS    1 
     1 19-APR-17 08.07.31.731745 PM SUCCESS    2 
     1 19-APR-17 08.07.32.735582 PM SUCCESS    3 
     2 19-APR-17 08.17.51.332804 PM FAIL    1 
     2 19-APR-17 08.17.52.336530 PM FAIL    2 
     2 19-APR-17 08.19.27.993327 PM SUCCESS    1 
     2 19-APR-17 08.25.54.860077 PM FAIL    1 
     2 19-APR-17 08.25.55.862830 PM SUCCESS    1 

...ステータス値が変更されるたびに「ランク」が開始されます(日付順)。私は、私が得ているアウトプットは全体的なステータスグループによってランク付けされていることを理解していますが、この出力を得るための関数の組み合わせを見つけることができませんでした。

このはほとんどはそれを取得しますが、ではない、かなり:

SELECT transid, launchtime, status, rnk 
    FROM (SELECT transid, 
       status, 
       launchtime, 
       RANK() OVER (PARTITION BY transid, status ORDER BY launchtime) rnk 
     FROM syntrans) 
ORDER BY transid, launchtime; 

答えて

1

あなたは一つのグループとして連続した同じステータス行を分類するために、行番号のアプローチの違いを使用することができます。 (内部クエリを実行して、グループの割り当て方法を確認してください)、次にこれらのグループにrow_numberを使用します。

SELECT transid, launchtime, status 
,ROW_NUMBER() over(PARTITION BY transid,grp ORDER BY launchtime) as rnk 
FROM (SELECT transid, 
       status, 
       launchtime, 
       ROW_NUMBER() OVER (PARTITION BY transid ORDER BY launchtime) 
       -ROW_NUMBER() OVER (PARTITION BY transid, status ORDER BY launchtime) as grp 
     FROM syntrans) t 
+0

私は必要な出力を得ています。私はdecode()とlag()を組み合わせたラビットソールを試してみましたが、row_number()の出力を減算することは考えていませんでした。 – dlivings

+0

@dlivings - 読んで勉強したいのであれば、 "Tabibitosan method"を検索してください。このテクニックの多くの例が見つかります。それは驚くほど多くの状況で有用であることがわかります。 – mathguy

+0

@mathguy - ありがとう、私はそのメソッドの名前があったのか分からなかった。すでに他のものが見つかったので、私はこれをOPとは別に使い直し、かなり複雑さを減らすことができます... – dlivings

関連する問題