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

Sql 根据列的不同值查询选择行,sql,derby,squirrel-sql,Sql,Derby,Squirrel Sql,我的当前查询有一个问题,我希望基于列获取记录/结果(示例列Status的值为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,

我的当前查询有一个问题,我希望基于列获取记录/结果(示例列Status的值为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条记录(show with min(CW_UPD_TMS))与现在的3条记录具有相同的状态(New)

我的预期结果应该是:

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

对不起,我的英语很差

它在您的案例中的预期行为。除了“Status”之外,您还应该提供另一个列,这样它们就可以形成复合键,复合键是唯一的,并且您可以得到它的单个记录

您可以有任何条件,如日期或任何适合您的要求的条件,并使用“行数”属性来限制带有1条记录的结果


让我知道这是否有意义。

这可能是一个好的开始,但我必须假设时间戳作为主键工作。你应该在问题中提到你在哪个平台上。如果我们了解联合会和工会的情况,情况可能会更干净

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

要获取最旧的记录,需要按日期对记录进行排序。所以你要做的是把table a和table c结合起来,给记录一个数字,每个状态中最老的记录为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;

在进行联合时,您不必指定DISTINCT,因为联合将删除重复的行。因此,如果它们的状态不同,您仍然希望看到这些行在每个组中保留具有最早时间戳的行?不要将日期或时间戳存储为字符,请使用日期或时间戳数据类型!另外,
如果b.CW\u S\u BR为空,那么a.CW\u S\u BR或者b.CW\u S\u BR end
可以写为
合并(b.CW\u S\BR,a.CW\u S\u BR)
,这更清楚。也许您需要具有新状态的“最旧”行?还是“新”的
DISTINCT
UNION
基本上都在工作:您提供的三行不同。您好,我认为您的方式是可行的,但我无法更改表格设计:(尝试您的查询获取此错误:列名'CW_UPD_TMS'位于FROM列表中的多个表中。我认为当内部联接r在那里时命中。这只是意味着您需要在最外层的
select
子句中限定该列。我想我原本以为我要编写
where in
而不是内部联接…嗨,抱歉说我的DBMS是Derby,我在Squirrel SqlOk上运行查询,所以它不是SQL Server,而是Apache Derby。上面的查询是标准SQL。其中最高级的是分析函数ROW_NUMBER,Derby从10.4版开始就支持它。您尝试过该查询吗?执行时出错-错误:语法错误:遇到“分区”在第22行,第26列。在告诉您从10.4版开始Derby中就可以使用ROW_编号之后,我从您那里了解到,这一行出现语法错误。您能猜出我的下一个问题吗?