Per omettere la riga dal risultato se una delle fonte righe per lo stesso id
ha value IS NULL
, una soluzione in Postgres sarebbe usare la funzione di aggregazione every()
o (sinonimo di ragioni storiche) bool_and()
nel HAVING
clausola:
SELECT id
, max(case when colID = 1 then value else '' end) AS fn
, max(case when colID = 2 then value else '' end) AS ln
, max(case when colID = 3 then value else '' end) AS jt
FROM tbl
GROUP BY id
HAVING every(value IS NOT NULL);
Spiega
Il tuo tentativo con un WHERE
clausola eliminerebbe solo uno riga sorgente per id = 3
nel tuo esempio (quello con colID = 1
), lasciandone altri due per lo stesso id
. Quindi otteniamo ancora una riga per id = 3
nel risultato dopo l'aggregazione.
Ma poiché non abbiamo una riga con colID = 1
, otteniamo una stringa vuota (nota:non un NULL
valore!) per fn
nel risultato per id = 3
.
Una soluzione più veloce in Postgres sarebbe usare crosstab()
. Dettagli:
Altri RDBMS
Mentre EVERY
è definito nello standard SQL:2008, molti RDBMS non lo supportano, presumibilmente perché alcuni di essi hanno implementazioni losche di tipo booleano. (Non perdendo nomi come "MySQL" o "Oracle" ...). Probabilmente puoi sostituire ovunque (incluso Postgres) con:
SELECT id
, max(case when colID = 1 then value else '' end) AS fn
, max(case when colID = 2 then value else '' end) AS ln
, max(case when colID = 3 then value else '' end) AS jt
FROM tbl
GROUP BY id
HAVING count(*) = count(value);
Perché count()
non conta i valori NULL. In MySQL c'è anche bit_and()
.Altro sotto questa domanda correlata: