2015-06-30 101 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