U kunt meerdere zoekopdrachten combineren met UNION
, maar alleen als de query's hetzelfde aantal kolommen hebben. Idealiter zijn de kolommen hetzelfde, niet alleen in gegevenstype, maar ook in hun semantische betekenis; MySQL geeft echter niet om de semantiek en zal verschillende datatypes afhandelen door iets meer generiek te casten - dus indien nodig zou overbelast de kolommen om verschillende betekenissen van elke tabel te hebben en bepaal vervolgens welke betekenis geschikt is in uw code op een hoger niveau (hoewel ik het niet aanraad om het op deze manier te doen).
Als het aantal kolommen verschilt, of als u een betere/minder overbelaste uitlijning van gegevens van twee query's wilt bereiken, kunt u dummy letterlijke kolommen invoegen in uw SELECT
verklaringen. Bijvoorbeeld:
SELECT t.cola, t.colb, NULL, t.colc, NULL FROM t;
U kunt zelfs enkele kolommen reserveren voor de eerste tabel en andere voor de tweede tabel, zodat ze NULL
zijn elders (maar onthoud dat de kolomnamen uit de eerste zoekopdracht komen, dus u kunt ervoor zorgen dat ze daar allemaal worden genoemd):
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;
U kunt proberen uw twee zoekopdrachten op deze manier op elkaar af te stemmen en ze vervolgens te combineren met een UNION
exploitant; door LIMIT
toe te passen naar de UNION
, je hebt je doel bijna bereikt:
(SELECT ...)
UNION
(SELECT ...)
LIMIT 10;
Het enige probleem dat overblijft is dat, zoals hierboven weergegeven, 10 of meer records uit de eerste tabel alle records uit de tweede zullen "duwen". We kunnen echter een ORDER BY
. gebruiken in de buitenste vraag om dit op te lossen.
Alles bij elkaar:
(
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;
Natuurlijk is het nu aan jou om te bepalen met welk type rij je te maken hebt terwijl je elke record in de resultatenset leest (stel voor dat je request_id
test en/of alert_id
voor NULL
waarden; als alternatief zou men een extra kolom aan de resultaten kunnen toevoegen die expliciet vermeldt uit welke tabel elk record afkomstig is, maar het zou equivalent moeten zijn op voorwaarde dat die id
kolommen zijn NOT NULL
).