2016-11-23 2 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.

의 난 때 케이스 IN 사용이 불가능하다는 오류가 발생

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

각 행에 대해? 각 신분증을 의미합니까? 넥타이의 경우 예상되는 결과는 무엇입니까? – 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'인지 확인할 수 있습니다.

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

:

는 (이 아래 ranked 공통 테이블 표현식에 표시되는 row_number() OLAP 기능을 사용 만 "최신"레코드를 선택할 수 있습니다 (단 최신 레코드) 최종 결과를 얻으려면 이

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은 예약 된 단어로 TIMESTAMP있다 d는 "TIMESTAMP"

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 

는 "TIMESTAMP"로 구분해야 할 수도 있으므로 ANSI SQL이 예약 된 단어로 TIMESTAMP있다