根据列的不同值查询选择行

时间:2015-06-30 08:51:54

标签: sql derby squirrel-sql

我的当前查询有问题,我希望获得基于列的记录/结果(如果有3条状态为new的记录,示例列Status将为执行的查询设置new / pending / completed的值,它应该是过滤器以显示仅有状态为新的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  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条记录(显示为min(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
抱歉我的英语不好。

3 个答案:

答案 0 :(得分:1)

在你的情况下它的预期行为。除了" Status"之外,您还应该提出另一个专栏。所以他们可以形成复合键,这将是唯一的,你可以获得它的单一记录。

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

如果这有意义,请告诉我。

答案 1 :(得分: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

答案 2 :(得分:0)

要获取最早的记录,您需要按日期对记录进行排名。所以你要做的就是组合TableA和TableC,给记录一个数字,每个状态最旧一个,然后只保留那些排名为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;