Du kan kombinera flera frågor med UNION
, men bara om frågorna har samma antal kolumner. Helst är kolumnerna desamma, inte bara i datatyp, utan också i sin semantiska betydelse; MySQL bryr sig dock inte om semantiken och kommer att hantera olika datatyper genom att övergå till något mer generiskt - så vid behov kan överbelasta kolumnerna så att de har olika betydelser från varje tabell och bestäm sedan vilken betydelse som är lämplig i din kod på högre nivå (även om jag inte rekommenderar att du gör det på det här sättet).
När antalet kolumner skiljer sig, eller när du vill uppnå en bättre/mindre överbelastad justering av data från två frågor, kan du infoga dummy literal-kolumner i din SELECT
uttalanden. Till exempel:
SELECT t.cola, t.colb, NULL, t.colc, NULL FROM t;
Du kan till och med ha vissa kolumner reserverade för den första tabellen och andra för den andra tabellen, så att de är NULL
någon annanstans (men kom ihåg att kolumnnamnen kommer från den första frågan, så du kanske vill försäkra dig om att de alla är namngivna där):
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;
Du kan prova att anpassa dina två frågor på det här sättet och sedan kombinera dem med en UNION
operatör; genom att använda LIMIT
till UNION
, du är nära att nå ditt mål:
(SELECT ...)
UNION
(SELECT ...)
LIMIT 10;
Det enda problemet som återstår är att, som presenterats ovan, 10 eller fler poster från den första tabellen kommer att "skjuta ut" alla poster från den andra. Däremot kan vi använda en ORDER BY
i den yttre frågan för att lösa detta.
Att sätta ihop allt:
(
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;
Naturligtvis är det nu upp till dig att avgöra vilken typ av rad du har att göra med när du läser varje post i resultatuppsättningen (föreslå att du testar request_id
och/eller alert_id
för NULL
värden; alternativt kan man lägga till ytterligare en kolumn till resultaten som uttryckligen anger vilken tabell varje post kommer från, men den bör vara likvärdig förutsatt att dessa id
kolumner är NOT NULL
).