Tenho estes dados:
select * from (
select 'A' as JOB, 15 as errors from dual union all
select 'B' as JOB, 17 as errors from dual union all
select 'C' as JOB, 29 as errors from dual union all
select 'D' as JOB, 27 as errors from dual union all
select 'E' as JOB, 35 as errors from dual union all
select 'F' as JOB, 32 as errors from dual union all
select 'G' as JOB, 75 as errors from dual union all
select 'H' as JOB, 31 as errors from dual union all
select 'I' as JOB, 12 as errors from dual union all
select 'J' as JOB, 10 as errors from dual
)
E, em palavras, eu preciso:The jobs constituting the (top) 60% of errors
Então, neste caso, seria (113):
select sum(errors) * .4 as cut_off from ...
Os resultados finais seriam estes, pois sua soma < 113:
TRABALHO | ERROS |
---|---|
G | 75 |
E | 35 |
Basicamente, preciso de um filtro que mantenha algum tipo de soma corrente e, depois, descarte tudo quando atingir esse valor.
Tenho essa consulta, que não funciona muito bem e eu preferiria não usar a with
declaração
with data as (
select 'A' as JOB, 15 as errors from dual union all
select 'B' as JOB, 17 as errors from dual union all
select 'C' as JOB, 29 as errors from dual union all
select 'D' as JOB, 27 as errors from dual union all
select 'E' as JOB, 35 as errors from dual union all
select 'F' as JOB, 32 as errors from dual union all
select 'G' as JOB, 75 as errors from dual union all
select 'H' as JOB, 31 as errors from dual union all
select 'I' as JOB, 12 as errors from dual union all
select 'J' as JOB, 10 as errors from dual
)
select k.*
from (
select t.*,
errors + LAG(errors, 1, 0) OVER (order by errors desc ) previous
from data t
) k where previous >= (select sum(errors) *.4 from data) order by errors desc
E eu tentei a soma em janela:
select k.*
from (
select t.*,
SUM(errors) OVER (
partition by JOB
order by errors desc
RANGE BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW
) as limit
from (
select 'A' as JOB, 15 as errors from dual union all
select 'B' as JOB, 17 as errors from dual union all
select 'C' as JOB, 29 as errors from dual union all
select 'D' as JOB, 27 as errors from dual union all
select 'E' as JOB, 35 as errors from dual union all
select 'F' as JOB, 32 as errors from dual union all
select 'G' as JOB, 75 as errors from dual union all
select 'H' as JOB, 31 as errors from dual union all
select 'I' as JOB, 12 as errors from dual union all
select 'J' as JOB, 10 as errors from dual
) t
) k order by errors desc
SUM(errors) OVER (ORDER BY errors DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
calcula o total de erros em ordem decrescente.WHERE cum_errors <= cut_off
filtra trabalhos com erros cumulativos abaixo de 40% do total.Saída:
violino
Outra lógica usando subconsulta e autojunção.
total_erros_cte:
Este CTE calcula o número total de erros da tabela jobs_errors. Ele simplesmente soma todos os erros na tabela.
soma_corrente_cte:
Este CTE calcula a soma cumulativa de erros em ordem decrescente. Para cada trabalho, ele soma os erros de todos os trabalhos que têm erros maiores ou iguais à contagem de erros do trabalho atual (ONDE x.errors >= t.errors). Ele também recupera o total_errors do total_errors_cte para comparar a soma corrente com 40% do total de erros.
Saída :
Violino