Chcete-li vynechat řádek z výsledku pokud některý ze zdrojů řádků pro stejné id
má value IS NULL
, řešení v Postgres by bylo použít agregační funkci every()
nebo (synonymum z historických důvodů) bool_and()
v HAVING
klauzule:
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);
Vysvětlete
Váš pokus s WHERE
klauzule by pouze odstranila jednu zdrojový řádek pro id = 3
ve vašem příkladu (ten s colID = 1
), ponechte dva další pro stejné id
. Stále tedy dostáváme řádek pro id = 3
ve výsledku po agregaci.
Ale protože nemáme žádný řádek s colID = 1
, dostaneme prázdný řetězec (poznámka:ne NULL
value!) pro fn
ve výsledku pro id = 3
.
Rychlejším řešením v Postgresu by bylo použití crosstab()
. Podrobnosti:
Další RDBMS
Zatímco EVERY
je definován ve standardu SQL:2008, mnoho RDBMS jej nepodporuje, pravděpodobně proto, že některé z nich mají stinné implementace typu boolean. (Nevypouštět žádná jména jako "MySQL" nebo "Oracle" ...). Pravděpodobně všude (včetně Postgresu) můžete nahradit:
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);
Protože count()
nepočítá hodnoty NULL. V MySQL je také bit_and()
.Více pod touto související otázkou: