2016-11-23 40 views
0

我有一个包含记录状态的表。事情是这样的:SQL案例取决于记录的先前状态

ID STATUS TIMESTAMP 
1 I 01-01-2016 
1 A 01-03-2016 
1 P 01-04-2016 
2 I 01-01-2016 
2 P 01-02-2016 
3 P 01-01-2016 

我想要,我把每行的最新版本的情况下,并有在一直是我的一些点的所有P,它们应该被包装为“G”,而不是P.

,当我试图做类似

Select case when ID in (select ID from TABLE where ID = 'I') else ID END as  status) 
From TABLE 
where ID in (select max(ID) from TABLE) 

我在使用套管时得到一个错误,这是不可能的。

所以我的问题是,我该怎么做呢?

想直到结束:

ID STATUS TIMESTAMP 
1 G 01-04-2016 
2 G 01-02-2016 
3 P 01-01-2016 

DBMS是IBM DB2

+0

我们正在使用IBM DB2 SQL,如果这是一个DBMS? – user2656595

+0

您尚未指定确切的DBMS – Viki888

+0

对于每一行?你是指每个ID?平局的预期结果是什么? – jarlh

回答

0

有一个派生表,返回其最新的时间戳每个ID。与结果加入:

select t1.ID, t1.STATUS, t1.TIMESTAMP 
from tablename t1 
join (select id, max(timestamp) as max_timestamp 
     from tablename 
     group by id) t2 
    ON t1.id = t2.id and t1.TIMESTAMP = t2.max_timestamp 

将在相同的情况下返回两行

需要注意的是ANSI SQL具有TIMESTAMP为保留字,所以你可能需要界定(有相同的最新时间戳两行。)它作为"TIMESTAMP"

0

您可以通过使用一个公共表表达式发现,有过'I'状态的所有ID,然后用你的表外连接,以确定哪个ID不得不在某些时候的'I'状态做到这一点。

得到最终的结果(只有最新的记录),你可以使用row_number() OLAP功能,只选择“最新的”记录(这显示在下面的ranked公用表表达式:

with irecs (ID) as (
    select distinct 
     ID 
    from 
     TABLE 
    where 
     status = 'I' 
), 
ranked as (
    select 
     rownumber() over (partition by t.ID order by t.timestamp desc) as rn, 
     t.id, 
     case when i.id is null then t.status else 'G' end as status, 
     t.timestamp 
    from 
     TABLE t 
     left outer join irecs i 
      on t.id = i.id 
) 
select 
    id, 
    status, 
    timestamp 
from 
    ranked 
where 
    rn = 1; 
0

试试这个

select distinct f1.id, f4.* 
from yourtable f1 
inner join lateral 
(
    select 
    case (select count(*) from yourtable f3 where f3.ID=f2.ID and f3."TIMESTAMP"<f2."TIMESTAMP" and f3.STATUS='I')>0 then 'G' else f2.STATUS end as STATUS, 
    f2."TIMESTAMP" 
    from yourtable f2 where f2.ID=f3.ID 
    order by f2."TIMESTAMP" desc, rrn(f2) desc 
    fetch first rows only 

) f4 on 1=1 

RRN(F2)命令是相同的最后日期

ANSI SQL具有时间戳的保留字,所以你可能东东d界定为“时间戳”

0

其他的解决办法

with youtableranked as (
select f1.id, 
case (select count(*) from yourtable f2 where f2.ID=f1.ID and f2."TIMESTAMP"<f1."TIMESTAMP" and f2.STATUS='I')>0 then 'G' else f1.STATUS end as STATUS, 
rownumber() over(partition by f1.id order by f1.TIMESTAMP desc, rrn(f1) desc) rang, 
f1."TIMESTAMP" 
from yourtable f1 
) 
select * from youtableranked f0 
where f0.rang=1 

ANSI SQL有时间戳的保留字,所以你可能需要划为“时间戳”