SQL Group By和Lag函数没有给出正确的输出

时间:2017-08-07 18:50:58

标签: sql group-by oracle-sqldeveloper lag partition

我有以下输出:

 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

如何获得所需的输出以及为什么我的查询(滞后函数)无法正常工作?

2 个答案:

答案 0 :(得分: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或类似的:

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;

答案 1 :(得分:0)

在对要检查的字段(TYPE和W_ID)执行延迟之后,您可以将其包装在另一个带有where子句的select语句中,该子句删除最后一个等于当前行的行。例如:

编辑我的第一个答案包括刚改变的所有行,我所做的就是接受该代码并将其包装以获取由ID分区的最高更改。

Type error: Argument 3 passed to App\Mail\OrderComplete::__construct() must be an instance of App\Document, instance of Illuminate\Database\Eloquent\Collection given, called in /Users/ap/sites/propair/app/Http/Controllers/OrderController.php on line 253

输出是:

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