Mysql
 sql >> Base de données >  >> RDS >> Mysql

MySQL :obtenir le dernier message de 2 tables associées l'une à l'autre

Dans les anciennes versions de MySQL (<8.0.2), nous pouvons utiliser Tables dérivées . Dans une table dérivée, nous pouvons obtenir le dernier send_datetime valeur pour chaque conversation_id . En outre, il convient de noter que vous pouvez fournir vos filtres pour conversation_id dans WHERE clause de cette sous-requête.

Nous pouvons ensuite utiliser le jeu de résultats de cette sous-requête et rejoindre les tables principales de manière appropriée, pour obtenir la ligne correspondant au dernier message d'une conversation.

Schéma (MySQL v5.7)

Voir sur DB Fiddle

Requête 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;

Résultat

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

Dans MySQL 8.0.2 et supérieur, nous pouvons utiliser Row_Number() Fonctionnalité. Dans une partition de conversation_id , nous déterminerons le numéro de ligne pour chaque message, trié par ordre décroissant de send_datetime . Dans cette sous-requête, vous pouvez fournir vos filtres pour conversation_id dans WHERE clause.

Nous utiliserons ensuite cet ensemble de résultats en tant que table dérivée et ne considérerons que les lignes, où la valeur du numéro de ligne est 1 (car il appartiendra au dernier send_datetime ).

Schéma (MySQL v8.0)

Voir sur DB Fiddle

Requête 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;

Résultat

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