Лучший запрос для получения соотношения успехов/неуспехов из таблицы фактов склада
-
15-11-2019 - |
Вопрос
Я пытаюсь уточнить запрос и хотел бы получить обратную связь.у меня есть job_fact
таблица склада с единицей измерения конечного события задания (final_event_type
).Я пытаюсь выполнить запрос по тому факту, который даст мне соотношение успеха/неудачи.Вот что у меня есть на данный момент:
SELECT
CASE WHEN jf.final_event_type IN (4,6,8,9) THEN count(final_event_type) END as num_failures,
CASE WHEN jf.final_event_type IN (5,7,10) THEN count(final_event_type) END as num_successes
FROM job_fact jf
GROUP BY jf.final_event_type;
Этот запрос дает мне только необработанные значения успеха и неудачи в двухстрочном результате:
+----------------------+-----------------------+
| num_failures | num_successes |
+----------------------+-----------------------+
| [NULL] | 6 |
| 14 | [NULL] |
+----------------------+-----------------------+
Кто-нибудь знает, есть ли способ: а) получить результаты в одной строке и б) иметь возможность рассчитать соотношение между ними (например,процент неудач).Я предполагаю, что кто-то скажет мне, что мне лучше написать процедуру для этого, но я хотел бы избежать этого, если это возможно.Я знаю, что есть элегантный способ сделать это, но, думаю, моего sql-foo сегодня не хватает.
Я использую PostgreSQL 9.0.1.Спасибо за любую помощь, которую вы можете предложить.
ОБНОВЛЯТЬ
Основываясь на выбранном ответе (от @Ronnis), вот мой последний вопрос, если вам интересно:
select
sum(case when final_event_type in(4,6,8,9) then 1 else 0 end) as failures,
sum(case when final_event_type in(5,7,10) then 1 else 0 end) as successes,
count(final_event_type) as total_events,
sum(case when final_event_type in(4,6,8,9) then 1 else 0 end) / count(final_event_type)::decimal as failure_percentage,
sum(case when final_event_type in(5,7,10) then 1 else 0 end) / count(final_event_type)::decimal as success_percentage
from job_fact;
Решение
Если where final_event_type in(4,5,6,7,8,9,10)
попадет в большую часть таблицы, я думаю, что следующее было бы довольно эффективно:
select sum(case when final_event_type in(4,6,8,9) then 1 else 0 end) as failures
,sum(case when final_event_type in(5,7,10) then 1 else 0 end) as successes
from job_fact;
Редактировать
Я не знаю, как postgresq выполняет приведенный выше запрос.В Oracle существует путь доступа под названием «Быстрое полное сканирование индекса», который по сути рассматривает индекс как таблицу.Никакого обхода (медленно), только полное сканирование (эффективно).Преимущество состоит в том, что индекс {final_event_type}
может быть значительно меньше для сканирования, чем вся таблица.(Я не упоминаю растровые индексы, потому что это будет еще быстрее).
Другие советы
SELECT num_failures, num_successesc, (num_failures/Total), (num_successesc/Total)
FROM (
SELECT
(SELECT COUNT(*) FROM job_fact WHERE final_event_type IN (4,6,8,9)) AS "num_failures"
(SELECT COUNT(*) FROM job_fact WHERE final_event_type IN (5,7,10)) AS "num_successesc"
(SELECT COUNT(*) FROM job_fact WHERE final_event_type IN (4,6,8,9,5,7,10)) AS "Total"
) PQ