Sie können mehrere Abfragen mit UNION
kombinieren
, aber nur, wenn die Abfragen die gleiche Anzahl von Spalten haben. Idealerweise sind die Spalten gleich, nicht nur im Datentyp, sondern auch in ihrer semantischen Bedeutung; MySQL kümmert sich jedoch nicht um die Semantik und behandelt unterschiedliche Datentypen, indem es in etwas Allgemeineres umwandelt - Sie könnten es also notfalls tun Überladen Sie die Spalten so, dass sie unterschiedliche Bedeutungen aus jeder Tabelle haben, und bestimmen Sie dann, welche Bedeutung in Ihrem Code auf höherer Ebene angemessen ist (obwohl ich es nicht empfehle, dies auf diese Weise zu tun).
Wenn die Anzahl der Spalten unterschiedlich ist oder wenn Sie eine bessere/weniger überladene Ausrichtung der Daten aus zwei Abfragen erreichen möchten, können Sie Dummy-Literalspalten in Ihr SELECT
einfügen Aussagen. Zum Beispiel:
SELECT t.cola, t.colb, NULL, t.colc, NULL FROM t;
Sie könnten sogar einige Spalten für die erste Tabelle und andere für die zweite Tabelle reservieren, sodass sie NULL
sind an anderer Stelle (aber denken Sie daran, dass die Spaltennamen aus der ersten Abfrage stammen, daher möchten Sie vielleicht sicherstellen, dass sie alle dort benannt sind):
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;
Sie könnten versuchen, Ihre beiden Abfragen auf diese Weise auszurichten und sie dann mit einer UNION
zu kombinieren Operator; durch Anwenden von LIMIT
an die UNION
, Sie haben Ihr Ziel fast erreicht:
(SELECT ...)
UNION
(SELECT ...)
LIMIT 10;
Das einzige Problem, das bleibt, ist, dass, wie oben dargestellt, 10 oder mehr Datensätze aus der ersten Tabelle alle Datensätze aus der zweiten "verdrängen". Wir können jedoch einen ORDER BY
verwenden in der äußeren Abfrage, um dies zu lösen.
Alles zusammen:
(
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;
Jetzt liegt es natürlich an Ihnen, zu bestimmen, mit welcher Art von Zeile Sie es zu tun haben, wenn Sie jeden Datensatz in der Ergebnismenge lesen (schlagen Sie vor, dass Sie request_id
testen und/oder alert_id
für NULL
Werte; Alternativ könnte man den Ergebnissen eine zusätzliche Spalte hinzufügen, die explizit angibt, aus welcher Tabelle jeder Datensatz stammt, aber es sollte äquivalent sein, vorausgesetzt, diese id
Spalten sind NOT NULL
).