我有一个我想基于字符串列聚合的数据集。数据集基本上是:
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和PRE2的sql,但是我不确定如何聚合字符串函数以便系统是:
我看过LISTAGG,但我认为不适用。
答案 0 :(得分: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, '^[^-]*')
答案 1 :(得分: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
答案 2 :(得分:0)
我会通过对回复进行排名来接近它。例如,将值设置为最不希望的结果所需的值:
SUCCESS = 1
RUNNING = 2
<blank> = 3
PENDING = 3
然后根据它选择一个min。
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
用文本格式很难做到,更容易用数字做。您为字符串分配的数字很重要,因为它们决定了您在最终查询中返回的单个值的多个值。
答案 3 :(得分: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