Désolé si mon titre est un peu déroutant, je ne savais pas comment le formuler.

J'ai un tableau qui représente un horaire de bus. Il comporte une entrée pour chaque arrêt effectué à chaque trajet effectué, ainsi que les heures d'arrivée et de départ, et l'ordre des arrêts. Ex:

Trip_ID  Arrival     Departure     Stop_ID  Stop_Seq
Trip1    06:00:00    06:00:30      465      1
Trip1    06:03:45    06:04:15      474      2
...
Trip1    06:53:15    06:53:45      169      27
Trip1    06:56:30    06:57:00      311      28
Trip2    07:02:00    07:02:30      534      1
Trip2    07:03:45    07:04:15      700      2
...
Trip2    07:41:50    07:42:20      164      35
Trip2    07:45:30    07:46:00      311      36

Mon objectif est d'écrire une requête qui renverra deux résultats pour chaque trajet unique, l'enregistrement avec le Stop_Seq le plus bas et l'enregistrement avec le Stop_Seq le plus élevé (par trajet). Ex:

Trip_ID  Arrival     Departure     Stop_ID  Stop_Seq
Trip1    06:00:00    06:00:30      465      1
Trip1    06:56:30    06:57:00      311      28
Trip2    07:02:00    07:02:30      534      1
Trip2    07:45:30    07:46:00      311      36

J'ai essayé de faire quelque chose comme ce qui suit, mais je n'ai pas une bonne compréhension de la logique Group By.

SELECT trip_id,arrival,departure,stop_id,MIN(stop_seq),MAX(stop_seq)
FROM stop_times
GROUP BY trip_id;

Malheureusement, cela me contrarie de ne pas aussi regrouper par heures et arrêter, mais cela ne fonctionnera pas, je ne veux pas tous les temps, seulement le premier et le dernier.

Toute aide que vous pouvez fournir serait grandement appréciée! :)

1
cdav3435 25 nov. 2017 à 06:03

3 réponses

Meilleure réponse

La requête suivante renverra chaque enregistrement Trip avec son plus bas Stop_Seq et le plus élevé Stop_Seq.

SELECT *
FROM stop_times a
WHERE a.Stop_Seq=(
    SELECT  MAX(b.Stop_Seq)
    FROM stop_times b
    WHERE a.Trip_ID=b.Trip_ID
)
or 
a.Stop_Seq=(
    SELECT  MIN(b.Stop_Seq)
    FROM stop_times b
    WHERE a.Trip_ID=b.Trip_ID
)
0
Abhilash Ravindran C K 25 nov. 2017 à 05:27

Si Stop_Seq est unique, vous pouvez utiliser une table dérivée. La table dérivée prend les Stop_Seq Min et Max de la table stop_times. La requête réceptrice peut se rejoindre pour récupérer les détails:

SELECT dT.Trip_ID
      ,ST.Arrival
      ,ST.Departure
      ,ST.Stop_ID
      ,dT.Stop_Seq

  FROM (
         SELECT Trip_ID, MIN(Stop_Seq) AS Stop_Seq FROM stop_times GROUP BY Trip_ID
         UNION ALL
         SELECT Trip_ID, MAX(Stop_Seq) FROM stop_times GROUP BY Trip_ID         
       ) AS dT 
           INNER JOIN stop_times ST 
             ON dT.Trip_ID = ST.Trip_ID
            AND dT.Stop_Seq = ST.Stop_Seq
ORDER BY Trip_ID   

Donne la sortie:

Trip_ID Arrival     Departure   Stop_ID Stop_Seq
Trip1   06:00:00    06:00:30    465     1
Trip1   06:56:30    06:57:00    311     28
Trip2   07:02:00    07:02:30    534     1
Trip2   07:45:30    07:46:00    311     36

Voici le code complet: http://sqlfiddle.com/#!6/b9efc/ 1/0

La raison pour laquelle cela n'a pas fonctionné comme prévu est que GROUP BY supprime les doublons, mais les valeurs des colonnes Arrivée, Départ et Stop_ID changent. Ces valeurs changeantes battent le GROUP BY.

1
Zorkolot 25 nov. 2017 à 03:31

Solution alternative. Calculez, à l'aide d'une sous-requête, dans deux requêtes distinctes, le stop_seq le plus bas par trajet et le stop_seq le plus élevé par trajet. Combinez les résultats à l'aide de UNION.

SELECT a.Trip_ID,a.Arrival, a.Departure, a.Stop_ID, a.Stop_Seq
FROM stop_times as a
WHERE a.Stop_Seq =
(
SELECT Min(b.Stop_Seq)
FROM stop_times as b
WHERE b.Trip_ID =a.Trip_ID
)
UNION SELECT a.Trip_ID,a.Arrival, a.Departure, a.Stop_ID, a.Stop_Seq
FROM stop_times as a
WHERE a.Stop_Seq =
(
SELECT Max(b.Stop_Seq)
FROM stop_times as b
WHERE b.Trip_ID =a.Trip_ID
);
0
Rene 25 nov. 2017 à 06:07
47482249