Pomocí UNION
můžete kombinovat více dotazů
, ale pouze v případě, že dotazy mají stejný počet sloupců. V ideálním případě jsou sloupce stejné nejen v datovém typu, ale také ve svém sémantickém významu; MySQL se však nestará o sémantiku a poradí si s různými datovými typy převedením na něco obecnějšího – takže v případě potřeby můžete přetížit sloupce, aby měly různé významy z každé tabulky, a pak určit, jaký význam je vhodný ve vašem kódu vyšší úrovně (ačkoli to nedoporučuji dělat tímto způsobem).
Když se počet sloupců liší nebo když chcete dosáhnout lepšího/méně přetíženého zarovnání dat ze dvou dotazů, můžete do SELECT
vložit fiktivní doslovné sloupce prohlášení. Například:
SELECT t.cola, t.colb, NULL, t.colc, NULL FROM t;
Dokonce můžete mít některé sloupce vyhrazené pro první tabulku a jiné pro druhou tabulku, takže jsou NULL
jinde (ale nezapomeňte, že názvy sloupců pocházejí z prvního dotazu, takže možná budete chtít zajistit, aby tam byly všechny pojmenovány):
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;
Můžete zkusit zarovnat své dva dotazy tímto způsobem a poté je zkombinovat s UNION
operátor; použitím LIMIT
do UNION
, jste blízko k dosažení svého cíle:
(SELECT ...)
UNION
(SELECT ...)
LIMIT 10;
Jediný problém, který zůstává, je, jak je uvedeno výše, 10 nebo více záznamů z první tabulky „vytlačí“ všechny záznamy z druhé tabulky. Můžeme však použít ORDER BY
ve vnějším dotazu, abyste to vyřešili.
Dát to všechno dohromady:
(
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;
Nyní je samozřejmě na vás, abyste při čtení každého záznamu v sadě výsledků určili, s jakým typem řádku máte co do činění (doporučujeme otestovat request_id
a/nebo alert_id
pro NULL
hodnoty; alternativně lze k výsledkům přidat další sloupec, který explicitně uvádí, ze které tabulky každý záznam pochází, ale měl by být ekvivalentní za předpokladu, že id
sloupce jsou NOT NULL
).