2016-09-08 54 views
2

我有一個數據集,我想根據字符串列進行聚合。數據集基本上是:試圖通過選擇幾個值中的一個來聚合字符串列

system  status 
------------------- 
PRE1-SYS1 SUCCESS 
PRE1-SYS2 SUCCESS 
PRE2-SYS1 RUNNING 
PRE2-SYS2 SUCCESS 
PRE3-SYS1 SUCCESS 
PRE3-SYS2 <blank> 

基本上,我希望這成爲:

system  status 
------------------- 
PRE1 SUCCESS 
PRE2 RUNNING 
PRE3 RUNNING 

我要修剪下來的價值體系PRE1所需的SQL,和PRE2,但我不知道如何聚集的字符串函數,這樣一個系統:

  • 唯一的成功,那麼狀態爲SUCCESS
  • 只有空值,那麼狀態PENDING
  • 任何其他組合,那麼在運行(成功/ RUNNING,成功/空,跑步/空)

我看了LISTAGG,但我不認爲它適用。

+0

要求仍不清楚。 「或者,如果並且只有,那麼PENDING」在英語中沒有意義,你想說什麼?你是說如果至少有一個'null',那麼狀態是PENDING?如果你有一行RUNNING和另一個'null' - 是PENDING還是RUNNING?請注意,LISTAGG與此無關。 – mathguy

+0

應該說空白,但我用尖括號,所以它HTML'd我。定影。 – dsbalaban

+0

感謝您的編輯。 PRE3顯示SUCCESS和'null',但結果是PENDING,但用文字說「如果只有NULL」,則爲「待處理」。這是什麼? – mathguy

回答

2

這裏是一個SQL查詢,你可以使用:

select regexp_substr(system, '^[^-]*') as prefix, 
     case 
      when count(status) = 0 then 'PENDING' 
      when count(*) = count(case when status = 'SUCCESS' then 1 end) then 'SUCCESS' 
      else 'RUNNING' 
     end as status 
from  mytable 
group by regexp_substr(system, '^[^-]*') 
+0

謝謝,這個很好用。對原帖中目標輸出的混淆抱歉。 – dsbalaban

+0

不客氣。 – trincot

+0

請不要忘記標記答案已被接受;-) – trincot

2
with 
    inputs (system, status) as (
     select 'PRE1-SYS1', 'SUCCESS' from dual union all 
     select 'PRE1-SYS2', 'SUCCESS' from dual union all 
     select 'PRE2-SYS1', 'RUNNING' from dual union all 
     select 'PRE2-SYS2', 'SUCCESS' from dual union all 
     select 'PRE3-SYS1', 'SUCCESS' from dual union all 
     select 'PRE3-SYS2', ''  from dual 
    ), 
    prep (system, flag) as (
     select substr(system, 1, instr(system, '-') - 1), 
       case status when 'SUCCESS' then 0 
          when 'RUNNING' then 1 else 2 end 
     from inputs 
    ) 
select system, 
     case when min(flag) = 2 then 'PENDING' 
      when max(flag) = 0 then 'SUCCESS' 
      else     'RUNNING' end as status 
from prep 
group by system 
order by system; 

輸出

SYSTEM STATUS 
--------- ------- 
PRE1  SUCCESS 
PRE2  RUNNING 
PRE3  RUNNING 
0

我會被排名的答覆接近它。例如,將一個值設置爲最想要的最不想要的結果:

SUCCESS = 1 
RUNNING = 2 
<blank> = 3 
PENDING = 3 

然後根據該值選擇最小值。

select xval = case status when 'Success' then 1 
          when 'Running' then 2 
          when 'Pending' then 3 
             else 3 
          end 

對您在此處獲得的值使用嵌套子選擇,因此每個系統只能獲得一條記錄。 選擇系統,閔(XVAL)

then display the 1 as Success 
      the 2 as Running 
      and 3 as Pending 

這是很難以文本格式做,容易做的數字。分配給字符串的數字非常重要,因爲它們確定何時有多個值在最終查詢中返回單個值。

0

另一種選擇。實際上,這最終與@ trincot的解決方案非常相似,我只是將邏輯從計算邏輯中分離出來。如果你的邏輯在未來變得更加複雜,這可能會更靈活一些。

with 
    inputs (system, status) as (
     select 'PRE1-SYS1', 'SUCCESS' from dual union all 
     select 'PRE1-SYS2', 'SUCCESS' from dual union all 
     select 'PRE2-SYS1', 'RUNNING' from dual union all 
     select 'PRE2-SYS2', 'SUCCESS' from dual union all 
     select 'PRE3-SYS1', 'SUCCESS' from dual union all 
     select 'PRE3-SYS2', ''  from dual 
    ), 
    /* The cnts CTE counts how many rows relate to a SYSTEM, 
     how many of those are SUCCESS, and how many are NULL. 
     */ 
    cnts(system, num_rows, num_success, num_null) as (
     select substr(system,1,instr(system, '-')-1) system, 
       count(*), 
       sum(case when status = 'SUCCESS' then 1 else 0 end), 
       sum(case when status is null then 1 else 0 end) 
     from inputs 
     group by substr(system,1,instr(system, '-')-1) 
    ) 
/* Using the counts from the CTE, we can implement whatever logic we 
    want 
*/ 
select system, 
     (case when num_rows = num_success then 'SUCCESS' 
      when num_rows = num_null then 'PENDING' 
      else 'RUNNING' 
     end) status 
    from cnts 
相關問題