web-dev-qa-db-fra.com

GROUP BY avec MAX (DATE)

J'essaie de lister la dernière destination (heure de départ MAX) pour chaque train dans un tableau, par exemple :

Train    Dest      Time
1        HK        10:00
1        SH        12:00
1        SZ        14:00
2        HK        13:00
2        SH        09:00
2        SZ        07:00

Le résultat souhaité devrait être:

Train    Dest      Time
1        SZ        14:00
2        HK        13:00

J'ai essayé d'utiliser

SELECT Train, Dest, MAX(Time)
FROM TrainTable
GROUP BY Train

par j'ai eu une erreur "ora-00979 pas une expression GROUP BY" en disant que je devais inclure "Dest" dans mon groupe par instruction. Mais ce n'est sûrement pas ce que je veux ...

Est-il possible de le faire dans une ligne de SQL?

135
Aries

Vous ne pouvez pas inclure dans votre jeu de résultats des colonnes non agrégées qui ne sont pas groupées. Si un train n'a qu'une seule destination, ajoutez simplement la colonne de destination à votre clause group by, sinon vous devez repenser votre requête.

Essayer:

SELECT t.Train, t.Dest, r.MaxTime
FROM (
      SELECT Train, MAX(Time) as MaxTime
      FROM TrainTable
      GROUP BY Train
) r
INNER JOIN TrainTable t
ON t.Train = r.Train AND t.Time = r.MaxTime
144
Oliver Hanappi
SELECT train, dest, time FROM ( 
  SELECT train, dest, time, 
    RANK() OVER (PARTITION BY train ORDER BY time DESC) dest_rank
    FROM traintable
  ) where dest_rank = 1
151
Thilo

Voici un exemple qui utilise uniquement une jointure à gauche et, à mon avis, est plus efficace que n'importe quel groupe en utilisant une méthode: Blog ExchangeCore

SELECT t1.*
FROM TrainTable t1 LEFT JOIN TrainTable t2
ON (t1.Train = t2.Train AND t1.Time < t2.Time)
WHERE t2.Time IS NULL;
75
Joe Meyer

Une autre solution:

select * from traintable
where (train, time) in (select train, max(time) from traintable group by train);
12
Claudio Negri

Tant qu'il n'y a pas de doublons (et que les trains ont tendance à arriver dans une seule gare à la fois) ...

select Train, MAX(Time),
      max(Dest) keep (DENSE_RANK LAST ORDER BY Time) max_keep
from TrainTable
GROUP BY Train;
8
Gary Myers

Je sais que je suis en retard à la fête, mais essayez ceci ...

SELECT 
    `Train`, 
    `Dest`,
    SUBSTRING_INDEX(GROUP_CONCAT(`Time` ORDER BY `Time` DESC), ",", 1) AS `Time`
FROM TrainTable
GROUP BY Train;

Src: Documentation de groupe

Edit: correction de la syntaxe sql

4
Gravy