Лучший запрос для получения отношения успеха / неудачи из таблицы фактов хранилища - PullRequest
1 голос
/ 18 февраля 2011

Я пытаюсь настроить запрос и хотел бы получить отзыв.У меня есть 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;

Ответы [ 2 ]

3 голосов
/ 18 февраля 2011

Если бы 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 есть путь доступа, называемый Index Fast Full scan, который в основном обрабатывает индекс как таблицу. Нет обхода (медленно), просто полное сканирование (эффективно). Преимущество состоит в том, что индекс на {final_event_type} может быть значительно меньше для сканирования, чем вся таблица. (Я не упоминаю растровые индексы, потому что это было бы еще быстрее).

1 голос
/ 18 февраля 2011
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
...