結果から行を省略するには ソースのいずれか 同じid
の行 value IS NULL
があります 、 Postgresのソリューション 集計関数を使用することになります every()
または(歴史的な理由による同義語) bool_and()
HAVING
で 条項:
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);
説明
WHERE
でのあなたの試み 句は1つを削除するだけです id =3
のソース行 あなたの例では( colID =1
の例 )、同じ id
にさらに2つ残します 。したがって、 id =3
の行は引き続き取得されます 集計後の結果に。
ただし、 colID =1
の行がないため 、空の文字列を取得します(注: NULL
ではありません 値!) fn
の場合 id =3
の結果 。
Postgresのより高速な解決策は、 crosstab()
を使用することです。 。詳細:
その他のRDBMS
EVERY
はSQL:2008標準で定義されており、多くのRDBMSはそれをサポートしていません。おそらく、それらのいくつかはブール型の怪しげな実装を持っているためです。 (「MySQL」や「Oracle」などの名前は削除しないでください...)。おそらくどこでも(Postgresを含む)次のように置き換えることができます:
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);
count()
NULL値はカウントされません。 MySQLには、 bit_and()
。この関連する質問の詳細: