Você pode combinar várias consultas com
UNION
, mas somente se as consultas tiverem o mesmo número de colunas. Idealmente, as colunas são as mesmas, não apenas no tipo de dados, mas também em seu significado semântico; no entanto, o MySQL não se importa com a semântica e lidará com diferentes tipos de dados convertendo para algo mais genérico - então, se necessário, você poderia sobrecarregue as colunas para que tenham significados diferentes de cada tabela e, em seguida, determine qual significado é apropriado em seu código de nível superior (embora eu não recomende fazê-lo dessa maneira). Quando o número de colunas é diferente, ou quando você deseja obter um alinhamento de dados melhor/menos sobrecarregado de duas consultas, você pode inserir colunas literais fictícias em seu
SELECT
declarações. Por exemplo:SELECT t.cola, t.colb, NULL, t.colc, NULL FROM t;
Você pode até ter algumas colunas reservadas para a primeira tabela e outras para a segunda tabela, de modo que sejam
NULL
em outro lugar (mas lembre-se de que os nomes das colunas vêm da primeira consulta, portanto, você pode querer garantir que todos sejam nomeados lá): 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;
Você pode tentar alinhar suas duas consultas dessa maneira e combiná-las com um
UNION
operador; aplicando LIMIT
para a UNION
, você está perto de atingir sua meta: (SELECT ...)
UNION
(SELECT ...)
LIMIT 10;
O único problema que permanece é que, conforme apresentado acima, 10 ou mais registros da primeira tabela "empurrarão" quaisquer registros da segunda. No entanto, podemos utilizar um
ORDER BY
na consulta externa para resolver isso. Juntando tudo:
(
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;
Claro, agora cabe a você determinar com que tipo de linha você está lidando enquanto lê cada registro no conjunto de resultados (sugiro que você teste
request_id
e/ou alert_id
para NULL
valores; alternativamente, pode-se adicionar uma coluna adicional aos resultados que indica explicitamente de qual tabela cada registro se originou, mas deve ser equivalente desde que id
colunas são NOT NULL
).