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: