Att utelämna raden från resultatet om någon av källan rader för samma id
har value IS NULL
, en lösning i Postgres skulle vara att använda aggregatfunktionen every()
eller (synonym av historiska skäl) bool_and()
i HAVING
klausul:
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);
Förklara
Ditt försök med en WHERE
klausul skulle bara eliminera en källrad för id = 3
i ditt exempel (det med colID = 1
), lämnar två till för samma id
. Så vi får fortfarande en rad för id = 3
i resultatet efter aggregering.
Men eftersom vi inte har någon rad med colID = 1
, får vi en tom sträng (obs:inte en NULL
värde!) för fn
i resultatet för id = 3
.
En snabbare lösning i Postgres skulle vara att använda crosstab()
. Detaljer:
Andra RDBMS
Medan EVERY
är definierad i SQL:2008-standarden, stöder många RDBMS inte det, förmodligen för att vissa av dem har skumma implementeringar av den booleska typen. (Inte släppa några namn som "MySQL" eller "Oracle" ...). Du kan förmodligen ersätta överallt (inklusive Postgres) med:
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);
Eftersom count()
räknar inte NULL-värden. I MySQL finns även bit_and()
.Mer under denna relaterade fråga: