Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MySQL:Obtenha a mensagem mais recente de 2 tabelas associadas uma à outra


Em versões mais antigas do MySQL (<8.0.2), podemos usar Tabelas Derivadas . Em uma tabela derivada, podemos obter o send_datetime mais recente valor para cada conversation_id . Além disso, vale ressaltar que você pode fornecer seus filtros para conversation_id em WHERE cláusula desta subconsulta.

Podemos então usar o conjunto de resultados desta subconsulta e voltar às tabelas principais apropriadamente, para obter a linha correspondente à mensagem mais recente em uma conversa.

Esquema (MySQL v5.7)

Ver no DB Fiddle

Consulta nº 1
SELECT
  amc.conversation_id, 
  m.message_id, 
  m.message   
FROM 
  assoc_message__conversation AS amc
JOIN message AS m 
  ON m.message_id = amc.message_id 
JOIN 
(
  SELECT
    amc1.conversation_id, 
    MAX(m1.send_datetime) AS latest_send_datetime
  FROM
   assoc_message__conversation AS amc1
  JOIN message AS m1
    ON m1.message_id = amc1.message_id 
  WHERE amc1.conversation_id IN (1,2)  -- Here you provide your input filters
  GROUP BY amc1.conversation_id
) AS dt  
  ON dt.conversation_id = amc.conversation_id AND 
     dt.latest_send_datetime = m.send_datetime;

Resultado
| conversation_id | message_id | message        |
| --------------- | ---------- | -------------- |
| 1               | 3          | Latest message |
| 2               | 6          | Latest message |

No MySQL 8.0.2 e acima, podemos usar Row_Number() funcionalidade. Dentro de uma partição de conversation_id , determinaremos o número da linha para cada mensagem, classificada em ordem decrescente de send_datetime . Nesta subconsulta, você pode fornecer seus filtros para conversation_id em WHERE cláusula.

Em seguida, usaremos esse conjunto de resultados como uma tabela derivada e consideraremos apenas as linhas, onde o valor do número da linha é 1 (pois pertencerá ao último send_datetime ).

Esquema (MySQL v8.0)

Ver no DB Fiddle

Consulta nº 2
SELECT 
  dt.conversation_id, 
  dt.message_id, 
  dt.message 
FROM 
(
  SELECT
    amc.conversation_id, 
    m.message_id, 
    m.message, 
    ROW_NUMBER() OVER (PARTITION BY amc.conversation_id 
                       ORDER BY m.send_datetime DESC) AS row_no 
  FROM
   assoc_message__conversation AS amc
  JOIN message AS m
    ON m.message_id = amc.message_id 
  WHERE amc.conversation_id IN (1,2)  -- Here you provide your input filters
) AS dt  
WHERE dt.row_no = 1;

Resultado
| conversation_id | message_id | message        |
| --------------- | ---------- | -------------- |
| 1               | 3          | Latest message |
| 2               | 6          | Latest message |