Лучший запрос для получения соотношения успехов/неуспехов из таблицы фактов склада

StackOverflow https://stackoverflow.com/questions/5042643

Вопрос

Я пытаюсь уточнить запрос и хотел бы получить обратную связь.у меня есть 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top