Untuk menghilangkan baris dari hasil jika ada sumber baris untuk id
yang sama memiliki value IS NULL
, solusi di Postgres akan menggunakan fungsi agregat every()
atau (sinonim untuk alasan historis) bool_and()
di HAVING
klausa:
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);
Jelaskan
Upaya Anda dengan WHERE
klausa hanya akan menghilangkan satu baris sumber untuk id = 3
dalam contoh Anda (yang dengan colID = 1
), sisakan dua lagi untuk id
yang sama . Jadi kita masih mendapatkan baris untuk id = 3
dalam hasil setelah digabungkan.
Tapi karena kita tidak memiliki baris dengan colID = 1
, kita mendapatkan string kosong (catatan:bukan NULL
nilai!) untuk fn
dalam hasil untuk id = 3
.
Solusi yang lebih cepat di Postgres adalah dengan menggunakan crosstab()
. Detail:
RDBMS lainnya
Sementara EVERY
didefinisikan dalam standar SQL:2008, banyak RDBMS tidak mendukungnya, mungkin karena beberapa di antaranya memiliki implementasi tipe boolean yang teduh. (Tidak menjatuhkan nama seperti "MySQL" atau "Oracle" ...). Anda mungkin dapat mengganti di mana saja (termasuk Postgres) dengan:
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);
Karena count()
tidak menghitung nilai NULL. Di MySQL juga ada bit_and()
.Lebih lanjut di bawah pertanyaan terkait ini: