Puede combinar múltiples consultas con UNION
, pero solo si las consultas tienen el mismo número de columnas. Idealmente, las columnas son las mismas, no solo en el tipo de datos, sino también en su significado semántico; sin embargo, MySQL no se preocupa por la semántica y manejará diferentes tipos de datos convirtiéndolos en algo más genérico, por lo que, si es necesario, podría sobrecargue las columnas para que tengan diferentes significados de cada tabla, luego determine qué significado es apropiado en su código de nivel superior (aunque no recomiendo hacerlo de esta manera).
Cuando el número de columnas difiere, o cuando desea lograr una alineación de datos mejor o menos sobrecargada de dos consultas, puede insertar columnas literales ficticias en su SELECT
declaraciones. Por ejemplo:
SELECT t.cola, t.colb, NULL, t.colc, NULL FROM t;
Incluso podría tener algunas columnas reservadas para la primera tabla y otras para la segunda tabla, de modo que sean NULL
en otro lugar (pero recuerde que los nombres de las columnas provienen de la primera consulta, por lo que es posible que desee asegurarse de que todos estén nombrados allí):
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;
Podría intentar alinear sus dos consultas de esta manera y luego combinarlas con una UNION
operador; aplicando LIMIT
a la UNION
, estás cerca de lograr tu objetivo:
(SELECT ...)
UNION
(SELECT ...)
LIMIT 10;
El único problema que queda es que, como se presentó anteriormente, 10 o más registros de la primera tabla "empujarán" cualquier registro de la segunda. Sin embargo, podemos utilizar un ORDER BY
en la consulta externa para resolver esto.
Poniendo todo junto:
(
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;
Por supuesto, ahora depende de usted determinar con qué tipo de fila está tratando a medida que lee cada registro en el conjunto de resultados (le sugerimos que pruebe request_id
y/o alert_id
para NULL
valores; alternativamente, se podría agregar una columna adicional a los resultados que indique explícitamente de qué tabla se originó cada registro, pero debería ser equivalente siempre que esos id
las columnas son NOT NULL
).