Anda dapat menggabungkan beberapa kueri dengan UNION
, tetapi hanya jika kueri memiliki jumlah kolom yang sama. Idealnya kolom-kolomnya sama, tidak hanya dalam tipe data, tetapi juga dalam arti semantiknya; namun, MySQL tidak peduli dengan semantik dan akan menangani tipe data yang berbeda dengan menggunakan sesuatu yang lebih umum - jadi jika perlu Anda bisa membebani kolom agar memiliki arti yang berbeda dari setiap tabel, lalu tentukan arti apa yang sesuai dalam kode tingkat yang lebih tinggi (walaupun saya tidak menyarankan melakukannya dengan cara ini).
Bila jumlah kolom berbeda, atau bila Anda ingin mencapai penyelarasan data yang lebih baik/kurang kelebihan beban dari dua kueri, Anda dapat menyisipkan kolom literal dummy ke SELECT
Anda pernyataan. Misalnya:
SELECT t.cola, t.colb, NULL, t.colc, NULL FROM t;
Anda bahkan dapat memiliki beberapa kolom yang dicadangkan untuk tabel pertama dan yang lainnya untuk tabel kedua, sehingga mereka NULL
di tempat lain (tetapi ingat bahwa nama kolom berasal dari kueri pertama, jadi Anda mungkin ingin memastikan semuanya diberi nama di sana):
SELECT a, b, c, d, NULL AS e, NULL AS f, NULL AS g FROM t1
UNION ALL -- specify ALL because default is DISTINCT, which is wasted here
SELECT NULL, NULL, NULL, NULL, a, b, c FROM t2;
Anda dapat mencoba menyelaraskan dua kueri dengan cara ini, lalu menggabungkannya dengan UNION
operator; dengan menerapkan LIMIT
ke UNION
, Anda hampir mencapai tujuan Anda:
(SELECT ...)
UNION
(SELECT ...)
LIMIT 10;
Satu-satunya masalah yang tersisa adalah, seperti yang disajikan di atas, 10 atau lebih catatan dari tabel pertama akan "mendorong" catatan apa pun dari tabel kedua. Namun, kita dapat menggunakan ORDER BY
di kueri luar untuk menyelesaikan ini.
Menyatukan semuanya:
(
SELECT
dr.request_time AS event_time, m.member_name, -- shared columns
dr.request_id, dr.member1, dr.member2, -- request-only columns
NULL AS alert_id, NULL AS alerter_id, -- alert-only columns
NULL AS alertee_id, NULL AS type
FROM dating_requests dr JOIN members m ON dr.member1=m.member_id
WHERE dr.member2=:loggedin_id
ORDER BY event_time LIMIT 10 -- save ourselves performing excessive UNION
) UNION ALL (
SELECT
da.alert_time AS event_time, m.member_name, -- shared columns
NULL, NULL, NULL, -- request-only columns
da.alert_id, da.alerter_id, da.alertee_id, da.type -- alert-only columns
FROM
dating_alerts da
JOIN dating_alerts_status das USING (alert_id, alertee_id)
JOIN members m ON da.alerter_id=m.member_id
WHERE
da.alertee_id=:loggedin_id
AND da.type='platonic'
AND das.viewed='0'
AND das.viewed_time<da.alert_time
ORDER BY event_time LIMIT 10 -- save ourselves performing excessive UNION
)
ORDER BY event_time
LIMIT 10;
Tentu saja, sekarang terserah Anda untuk menentukan jenis baris apa yang Anda hadapi saat Anda membaca setiap catatan di hasil (sarankan Anda menguji request_id
dan/atau alert_id
untuk NULL
nilai-nilai; sebagai alternatif, seseorang dapat menambahkan kolom tambahan ke hasil yang secara eksplisit menyatakan dari tabel mana setiap record berasal, tetapi harus setara asalkan id
tersebut kolom adalah NOT NULL
).