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! :)
3 réponses
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
)
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.
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
);
De nouvelles questions
sql
Le langage de requête structuré (SQL) est un langage permettant d'interroger des bases de données. Les questions doivent inclure des exemples de code, une structure de table, des exemples de données et une balise pour l'implémentation du SGBD (par exemple MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2, etc.) utilisés. Si votre question concerne uniquement un SGBD spécifique (utilise des extensions / fonctionnalités spécifiques), utilisez plutôt la balise de ce SGBD. Les réponses aux questions marquées avec SQL doivent utiliser le standard SQL ISO / IEC.