Mysql
 sql >> Database >  >> RDS >> Mysql

MySql, Postgres, Oracle e SQLServer ignorando il filtro NON È NULL

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

SQL Fiddle.

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: