Miglior query per ottenere il rapporto successo / fallimento dalla tabella dei fatti del magazzino

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

Domanda

Sto cercando di sintonizzare una query e vorrei un feedback. Ho un tavolo da magazzino job_fact con un'unità di misura per l'evento finale del lavoro (final_event_type). Sto cercando di eseguire una query sul fatto che mi darà un rapporto successo / fallimento. Ecco cosa ho finora:

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;
.

Questa query mi dà solo i veri valori di successo e guasto in un risultato a due fili:

+----------------------+-----------------------+
| num_failures         | num_successes         |
+----------------------+-----------------------+
| [NULL]               | 6                     |
| 14                   | [NULL]                |
+----------------------+-----------------------+
.

Qualcuno sa se c'è un modo per a) ottenere i risultati su una riga, e b) essere in grado di calcolare il rapporto tra i due (ad esempio la percentuale di guasto). Suppongo che qualcuno mi dimarmi che sto meglio a scrivere una procedura per questo, ma mi piacerebbe evitarlo se possibile. So che c'è un modo elegante per farlo, ma il mio sql-foo è carente oggi credo.

Sto eseguendo postgresql 9.0.1. Grazie per qualsiasi assistenza che puoi offrire.

Aggiornamento

Basato sulla risposta scelta (da @ronnis), ecco la mia query finale, nel caso ti stessi chiedendo:

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;
.

È stato utile?

Soluzione

If where final_event_type in(4,5,6,7,8,9,10) would hit most of the table, I think the following would be pretty performant:

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;

Edit
I don't know how postgresq executes the above query. In Oracle, there is an access path called Index Fast Full scan, which basically treats the index as a table. No traversal (slow), just a full scan (efficient). The benefit is that an index on {final_event_type} could be significantly smaller to scan than the whole table. (I'm not mentioning bitmap indexes, because that would be faster still).

Altri suggerimenti

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top