2017-08-07 48 views
0

我有以下的輸出:SQL GROUP BY和滯後功能沒有給予正確的輸出

last_login     | id | type | w_id 
    11/9/2016 10:59:13 PM | 123 | Thing1 | W1 
    11/9/2016 10:59:15 PM | 123 | Thing1 | W1 
    11/9/2016 10:59:15 PM | 123 | Thing1 | W3 
    11/10/2016 10:59:13 PM | 123 | Thing2 | W2 
    11/11/2016 10:59:13 PM | 123 | Thing1 | W1 
    11/12/2016 10:59:13 PM | 123 | Thing1 | W1 
    11/12/2016 10:59:13 PM | 345 | Thing1 | W4 
    11/13/2016 10:59:13 PM | 345 | Thing1 | W1 
    11/14/2016 10:59:13 PM | 345 | Thing2 | W2 
    11/15/2016 10:59:13 PM | 345 | Thing2 | W5 
    11/16/2016 10:59:13 PM | 345 | Thing1 | W1 
    11/16/2016 10:59:13 PM | 345 | Thing1 | W1 
    11/17/2016 10:59:13 PM | 345 | Thing1 | W4 
    11/17/2016 10:59:13 PM | 345 | Thing1 | W4 

爲以下查詢:

select sa.last_login, ad.ID, sa.type, w_id, 
from table1 dcc 
join table2 AD 
on AD.ID=DCC.id 

JOIN table3 sa 
ON AD.ID=sa.id 
join table4 sc 
on dcc.id=sc.id 
where sic3=‘Something’ 
order by dcc.id, sa.last_login 

我想大概是這樣的輸出:

last_login    | id | old_type | type | old_w_id | w_id 
11/11/2016 10:59:13 PM | 123 | Thing2 | Thing1 | W2  | W1 
11/17/2016 10:59:13 PM | 345 | Thing1 | Thing1 | W1  | W4 

我正在嘗試以下列方式執行此操作:

select 

t.last_login, t.id, t.old_type, t.type , t.old_w_id, t.w_id 

from 

(select sa.last_login, ad.id, sa.type, 
lag(sa.type, 1) over (partition by ad.id order by sa.last_login) as old_type, w_id, 
lag(w_id, 1) over (partition by ad.ID order by sa.last_login) as old_w_id from table1 dcc 

join table2 AD 
on ad.id=DCC.id 

JOIN table3 sa 
ON AD.ID=sa.id 

join table4 sc 
on dcc.id=sc.id 

where sc.si=’Something’ 
order by dcc.id, sa.last_login) t 

where t.old_type like ’THING1’ and t.type like ‘THING2’ 

group by t.id, t.id, t.old_type, t.type, t.w_id, t.old_w_id 

但我發現了的像這樣的輸出:

last_login    | id | old_type | type | old_w_id | w_id 
11/11/2016 10:59:13 PM | 123 | Thing1 | Thing2 | W1  | W2 

如何獲得所需的輸出,爲什麼我的查詢(滯後功能)不能正常工作?

+0

什麼'by'有這個查詢做組? –

+0

這是一個巨大的表,每個ID有多個條目。 – akrama81

+0

@GordonLinoff在我的問題中編輯表格輸出和需要的輸出以獲得更好的想法 – akrama81

回答

0

你不需要這個子查詢。只需使用lag()

select sa.last_login, ad.ID, sa.type, w_id, 
     lag(sa.type) over (partition by ad.id order by sa.last_login) as prev_type, 
     lag(sa.w_id) over (partition by ad.id order by sa.last_login) as prev_w_id 
from table1 dcc join 
    table2 AD 
    on AD.ID = DCC.id join 
    table3 sa 
    on AD.ID = sa.id join 
    table4 sc 
    on dcc.id = sc.id 
where sic3 = 'Something' 
order by dcc.id, sa.last_login 

如果你只是想最後一排,你可以使用fetch first 1 row only或sometihng,如:

select * 
from (select sa.last_login, ad.ID, sa.type, w_id, 
      lag(sa.type) over (partition by ad.id order by sa.last_login) as prev_type, 
      lag(sa.w_id) over (partition by ad.id order by sa.last_login) as prev_w_id, 
      row_number() over (partition by ad.id order by sa.last_login desc) as seqnum 
     from table1 dcc join 
      table2 AD 
      on AD.ID = DCC.id join 
      table3 sa 
      on AD.ID = sa.id join 
      table4 sc 
      on dcc.id = sc.id 
     where sic3 = 'Something' 
    ) t 
where seqnum = 1 
order by id, last_login; 
+0

不,我不需要最後一行,因爲如上面的示例(對於id 123)所示,最後兩行是Thing1,Thing1 &W1,W1,但是我想要Thing1,Thing2&W1,W2。每當上一次發生任何類型或w_id的更改時,我都想要。 – akrama81

0

您要查詢(TYPE和W_ID)領域做一個滯後之後,你可以用另外一個select語句來包裝它,用where子句去掉最後一個等於當前行的行。例如:

編輯我的第一個答案包括它只是改變了所有行,我所做的就是採取的代碼,將其套搶在ID劃分的最高變化。

create table Testing 
(
    last_login date, 
    id number, 
    type varchar2(50), 
    w_id varchar2(2) 
); 

insert into Testing values(to_date('11/09/2016 10:59:13 PM','MM/DD/YYYY HH:MI:SS PM'),123,'Thing1','W1'); 
insert into Testing values(to_date('11/09/2016 10:59:15 PM','MM/DD/YYYY HH:MI:SS PM'),123,'Thing1','W1'); 
insert into Testing values(to_date('11/09/2016 10:59:15 PM','MM/DD/YYYY HH:MI:SS PM'),123,'Thing1','W3'); 
insert into Testing values(to_date('11/10/2016 10:59:13 PM','MM/DD/YYYY HH:MI:SS PM'),123,'Thing2','W2'); 
insert into Testing values(to_date('11/11/2016 10:59:13 PM','MM/DD/YYYY HH:MI:SS PM'),123,'Thing1','W1'); 
insert into Testing values(to_date('11/12/2016 10:59:13 PM','MM/DD/YYYY HH:MI:SS PM'),123,'Thing1','W1'); 
insert into Testing values(to_date('11/12/2016 10:59:13 PM','MM/DD/YYYY HH:MI:SS PM'),345,'Thing1','W4'); 
insert into Testing values(to_date('11/13/2016 10:59:13 PM','MM/DD/YYYY HH:MI:SS PM'),345,'Thing1','W1'); 
insert into Testing values(to_date('11/14/2016 10:59:13 PM','MM/DD/YYYY HH:MI:SS PM'),345,'Thing2','W2'); 
insert into Testing values(to_date('11/15/2016 10:59:13 PM','MM/DD/YYYY HH:MI:SS PM'),345,'Thing2','W5'); 
insert into Testing values(to_date('11/16/2016 10:59:13 PM','MM/DD/YYYY HH:MI:SS PM'),345,'Thing1','W1'); 
insert into Testing values(to_date('11/16/2016 10:59:13 PM','MM/DD/YYYY HH:MI:SS PM'),345,'Thing1','W1'); 
insert into Testing values(to_date('11/17/2016 10:59:13 PM','MM/DD/YYYY HH:MI:SS PM'),345,'Thing1','W4'); 
insert into Testing values(to_date('11/17/2016 10:59:13 PM','MM/DD/YYYY HH:MI:SS PM'),345,'Thing1','W4'); 

select LAST_LOGIN, ID, TYPE, W_ID, TypeLag, W_IDLag 
from(
select LAST_LOGIN, ID, TYPE, W_ID, TypeLag, W_IDLag, 
     rank() over(partition by id order by last_login desc) RankOrder 
from(
select Testing.*, 
     lag(TYPE,1) over(partition by ID order by last_login) TypeLag, 
     lag(W_ID,1) over(partition by ID order by last_login) W_IDLag 
from Testing) 
where (nvl(TypeLag,'X') <> TYPE 
    or nvl(W_IDLag,'X') <> W_ID) 
) 
where RankOrder = 1 

輸出是:

LAST_LOGIN ID  TYPE W_ID TYPELAG  W_IDLAG 
11-NOV-16 123  Thing1 W1  Thing2  W2 
17-NOV-16 345  Thing1 W4  Thing1  W1 
+0

這不會給id 345的預期輸出 – akrama81

+0

這給出剛發生更改的所有行。再次閱讀您的問題,您是否只需要每個ID一行? –

+0

是的,我已經在我的問題中顯示了預期的輸出 – akrama81