1
votes

MySQL - Comment utiliser une sous-requête corrélée dans un JOIN

J'ai deux tables, Objects et Events.

Objects est structuré comme:

SELECT ID, IFNULL(e.Type, 1)
FROM objects o
LEFT JOIN (
    SELECT e.Object, e.Date, e.Type
    FROM events e
    WHERE e.Object = o.ID
    ORDER BY e.Date DESC
    LIMIT 1
) AS e ON e.Object = o.ID


2 commentaires

Quelle est votre sortie attendue pour cet exemple de données?


J'ai juste besoin d'un identifiant et d'un type. C'est pourquoi j'ai utilisé SELECT ID, IFNULL (e.Type, 1) .


4 Réponses :


0
votes
SELECT ID, IFNULL(e.Type, 1)
FROM objects o
LEFT JOIN (
    SELECT e.Object, max(e.Date), e.Type
    FROM events e
    GROUP BY e.Date DESC
) AS e ON e.Object = o.ID

2 commentaires

Non, car cela ne renvoie que le dernier événement joint à ses informations d'objet, alors que j'ai besoin du dernier événement pour chaque objet.


Ah, maintenant je comprends. Ensuite, vous devez agréger les lignes de la sous-requête. Quelque chose comme la réponse modifiée



0
votes

Vous pouvez essayer quelque chose comme ceci:

+------+------------+------+
| id   | date       | type |
+------+------------+------+
|    0 | 2020-06-02 |    1 |
|    0 | 2020-06-01 |    0 |
+------+------------+------+

sortie

SELECT o.id, max(e.date) AS date, e.type
FROM objects o
INNER JOIN events e ON(o.id = e.object)
GROUP BY o.id, e.type
ORDER BY e.date DESC;

J'espère que cela vous aidera.


0 commentaires

2
votes

Utilisez NOT EXISTS dans Events pour renvoyer uniquement la dernière ligne par Date:

> ID | Type
> -: | ---:
>  0 |    1
>  1 |    1

ou:

SELECT 
  o.ID, 
  IFNULL((SELECT e.Type FROM Events e WHERE e.Object = o.ID ORDER BY e.Date DESC LIMIT 1), 1) Type
FROM Objects o

Voir la démo .
Résultats:

SELECT ID, IFNULL(e.Type, 1) Type
FROM Objects o
LEFT JOIN (
    SELECT e.Object, e.Type
    FROM Events e
    WHERE NOT EXISTS (
      SELECT 1 FROM Events
      WHERE Object = e.Object AND Date > e.Date 
    ) 
) AS e ON e.Object = o.ID


0 commentaires

0
votes

Si vous avez la version 8 ou supérieure, vous pouvez utiliser la fonction row_number () pour calculer la dernière ligne

select * from
(
select id,coalesce(type,1) type,coalesce(date,date(now())) as dt,
         row_number() over (partition by o.id order by coalesce(date,date(now())) desc) rn
from  objects o
left join events e on e.object = o.id
order by o.id,dt desc
) s
where rn = 1;


0 commentaires