2015-06-30 56 views
2

我对当前查询有问题,我希望获得基于列的记录/结果(示例列Status对于查询i具有new/pending/completed的值如果有3个状态为new的记录,则执行该操作,它应该过滤为只显示1个状态为new的记录)。下面是我目前的查询获得重复列。查询选择基于列的不同值的行

select a.CW_UPD_TMS, 
      case when a.CW_CRT_UID='AAA' then 'BBB' 
       else a.CW_CRT_UID end as CW_CRT_UID, 
      COALESCE(b.CW_S_BR, a.CW_S_BR) as CW_S_BR, 
      a.CW_TRX_STAT as STATUS, 
      SUBSTR(a.CW_UPD_TMS,7,2) as day, 
      SUBSTR(a.CW_UPD_TMS,5,2) as month, 
      SUBSTR(a.CW_UPD_TMS,1,4) as ayear, 
      SUBSTR(a.CW_UPD_TMS,9,2) as hours, 
      SUBSTR(a.CW_UPD_TMS,11,2) as mins, 
      SUBSTR(a.CW_UPD_TMS,13,2) as secs, 
      case when cast(SUBSTR(a.CW_UPD_TMS,9,2) as INT) > 12 then 'PM' 
       else 'AM' end as zone 
from TABLEA a 
    left outer join TABLEB b on a.CW_CRT_UID = b.CW_S_USR 
where a.CW_TRX_ID = '20150415110000798' 
union 
select a.CW_UPD_TMS, 
      case when a.CW_CRT_UID='AAA' then 'BBB' 
       else a.CW_CRT_UID end as CW_CRT_UID, 
      COALESCE(b.CW_S_BR, a.CW_S_BR) as CW_S_BR, 
      a.CW_TRX_STAT as STATUS, 
      SUBSTR(a.CW_UPD_TMS,7,2) as day, 
      SUBSTR(a.CW_UPD_TMS,5,2) as month, 
      SUBSTR(a.CW_UPD_TMS,1,4) as ayear, 
      SUBSTR(a.CW_UPD_TMS,9,2) as hours, 
      SUBSTR(a.CW_UPD_TMS,11,2) as mins, 
      SUBSTR(a.CW_UPD_TMS,13,2) as secs, 
      case when cast(SUBSTR(a.CW_UPD_TMS,9,2) as INT) > 12 then 'PM' 
       else 'AM' end as zone 
from TABLEC a 
    left outer join TABLEB b on a.CW_CRT_UID = b.CW_S_USR 
where a.CW_TRX_ID = '20150415110000798' 

这是当前的结果:

CW_UPD_TMS   CW_CRT_UID CW_S_BR STATUS DAY MONTH AYEAR HOURS MINS SECS ZONE 
2015062610260746811 happy  KLC  NEW  26 06  2015 10  26  07  AM 
2015062610273984711 happy  KLC  NEW  26 06  2015 10  27  39  AM 
2015062610275762511 happy  KLC  NEW  26 06  2015 10  27  57  AM 

所以现在如何更改查询,以便只显示1只记录(秀分钟(CW_UPD_TMS))作为现在3记录有相同的状态(新)。

我预期的结果应该是:

CW_UPD_TMS   CW_CRT_UID CW_S_BR STATUS DAY MONTH AYEAR HOURS MINS SECS ZONE 
2015062610260746811 happy  KLC  NEW  26 06  2015 10  26  07  AM 

对不起我的英文不好。

+2

您不必指定DISTINCT,当你做一个UNION,因为UNION会删除重复的行。 – jarlh

+0

因此,如果他们并不都具有相同的状态,那么您仍然希望看到那些行保持每个组中具有最早时间戳的行? – shawnt00

+0

不要将日期或时间戳存储为字符,请使用DATE或TIMESTAMP数据类型! – jarlh

回答

1

它的预期行为在你的情况。除了“状态”之外,你应该想出另一个列,这样他们就可以形成组合键,这将是唯一的,并且你会得到单个记录。

您可以拥有符合您要求的日期或任何标准,并使用行号属性来限制1条记录的结果。

让我知道这是否有意义。

+0

嗨,我认为你的方式是工作,但我不能改变表设计:( – FruitLai

0

这可能是一个好的开始,但我不得不假定时间戳作为主键。你应该提到你在这个问题上的哪个平台。如果我们理解加入者和工会的情况,它也可能更清晰。

select 
    d.CW_UPD_TMS, CW_CRT_UID, CW_S_BR, STATUS, day, month, ayear, hours, mins, secs, zone 
from 
(
    select 
     a.CW_UPD_TMS, case when a.CW_CRT_UID='AAA' then 'BBB' else a.CW_CRT_UID end as CW_CRT_UID, 
     case when b.CW_S_BR is null then a.CW_S_BR else b.CW_S_BR end as CW_S_BR, a.CW_TRX_STAT as STATUS, 
     SUBSTR(a.CW_UPD_TMS,7,2) as day, SUBSTR(a.CW_UPD_TMS,5,2) as month, SUBSTR(a.CW_UPD_TMS,1,4) as ayear, 
     SUBSTR(a.CW_UPD_TMS,9,2) as hours, SUBSTR(a.CW_UPD_TMS,11,2) as mins,SUBSTR(a.CW_UPD_TMS,13,2) as secs, 
     case when cast(SUBSTR(a.CW_UPD_TMS,9,2) as INT) > 12 then 'PM' else 'AM' end as zone 
    from TABLEA a left outer join TABLEB b on a.CW_CRT_UID = b.CW_S_USR 
    where a.CW_TRX_ID = '20150415110000798' 
    union 
    select 
     a.CW_UPD_TMS, case when a.CW_CRT_UID='AAA' then 'BBB' else a.CW_CRT_UID end as CW_CRT_UID, 
     case when b.CW_S_BR is null then a.CW_S_BR else b.CW_S_BR end as CW_S_BR, a.CW_TRX_STAT as STATUS, 
     SUBSTR(a.CW_UPD_TMS,7,2) as day, SUBSTR(a.CW_UPD_TMS,5,2) as month, SUBSTR(a.CW_UPD_TMS,1,4) as ayear, 
     SUBSTR(a.CW_UPD_TMS,9,2) as hours, SUBSTR(a.CW_UPD_TMS,11,2) as mins,SUBSTR(a.CW_UPD_TMS,13,2) as secs, 
     case when cast(SUBSTR(a.CW_UPD_TMS,9,2) as INT) > 12 then 'PM' else 'AM' end as zone 
    from TABLEC a 
    left outer join TABLEB b on a.CW_CRT_UID = b.CW_S_USR 
    where a.CW_TRX_ID = '20150415110000798' 
) as d /* data */ inner join 
(
    select min(CW_UPD_TMS) as CW_UPD_TMS, CW_TRX_STAT 
    from (
     select a.CW_UPD_TMS, a.CW_TRX_STAT 
     from TABLEA a 
     where a.CW_TRX_ID = '20150415110000798' 
     union 
     select c.CW_UPD_TMS, c.CW_TRX_STAT 
     from TABLEC c 
     where c.CW_TRX_ID = '20150415110000798' 
    ) t0 
    group by CW_TRX_STAT 
) as r /* representative */ 
    on r.CW_UPD_TMS = d.CW_UPD_TMS and r.CW_TRX_STAT = d.CW_TRX_STAT 
+0

试图让你的查询得到这个错误:列名'CW_UPD_TMS'是在FROM列表中的多个表。我认为打内部连接r时有。 – FruitLai

+0

这只意味着您需要限定最外面的'select'子句中的该列。我想我原本以为我会写'在哪里'而不是内部连接... – shawnt00

0

要获取最旧的记录,您需要按日期对记录进行排名。所以,你会做的是结合表A和表C,给记录的数量,以1为每个状态的最古老的,那么只保留这些记录排名1.

select a.cw_upd_tms, 
    case when a.cw_crt_uid='AAA' then 'BBB' 
     else a.cw_crt_uid end as cw_crt_uid, 
    coalesce(b.cw_s_br, a.cw_s_br) as cw_s_br, 
    a.cw_trx_stat as status, 
    substr(a.cw_upd_tms,7,2) as day, 
    substr(a.cw_upd_tms,5,2) as month, 
    substr(a.cw_upd_tms,1,4) as ayear, 
    substr(a.cw_upd_tms,9,2) as hours, 
    substr(a.cw_upd_tms,11,2) as mins, 
    substr(a.cw_upd_tms,13,2) as secs, 
    case when cast(substr(a.cw_upd_tms,9,2) as int) > 12 then 'PM' 
     else 'AM' end as zone 
from 
(
    select 
    cw_trx_stat, cw_crt_uid, cw_upd_tms 
    from 
    (
    select 
     cw_trx_stat, cw_crt_uid, cw_upd_tms, 
     row_number() over (partition by cw_trx_stat order by cw_upd_tms) as rn 
    from 
    (
     select cw_trx_stat, cw_crt_uid, cw_upd_tms 
     from tablea where cw_trx_id = '20150415110000798' 
     union all 
     select cw_trx_stat, cw_crt_uid, cw_upd_tms 
     from tablec where cw_trx_id = '20150415110000798' 
    ) combined 
) ranked 
    where rn = 1 
) a 
left outer join tableb b on a.cw_crt_uid = b.cw_s_usr; 
+0

嗨,很抱歉,说我的DBMS是德比,我运行查询松鼠SQL – FruitLai

+0

好吧,所以它不是SQL Server,但是Apache Derby。以上查询是标准的SQL。其中最先进的东西是分析函数ROW_NUMBER,Derby支持从10.4版本开始。你有没有试过查询? –

+0

在执行过程中遇到错误 - 错误:语法错误:在第22行第26列遇到“分区”。 – FruitLai