2017-04-20 53 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方法」 - 你會發現這種技術的很多例子(這就是它所稱的)。它在許多情況下都有用。 – mathguy

+0

@mathguy - 謝謝,我不知道那個方法有個名字。已經找到了別的東西,我可以重新使用它(除OP之外)並減少相當多的複雜性。 – dlivings