SQL: première ligne de groupe après la jointure et l'ordre

En supposant que nous avons deux tables ci-dessous:

TravelTimes

OriginId DestinationId TotalJourneyTime 1 1 10 1 2 20 2 2 30 2 3 40 1 3 50 

Destinations

 DestinationId Name 1 Destination 1 2 Destination 2 3 Destination 3 

Comment puis-je find le trajet le plus rapide entre chaque origine et destination?
Je veux join TravelTimes avec Destinations par DestinationId, puis les grouper par OriginId et sortinger chaque groupe par TotalJourneyTime et sélectionner la première ligne de chaque groupe.
J'ai essayé de joindre et de grouper, mais il semble que le groupe par n'est pas la solution pour mon cas car je n'ai aucune colonne d'agrégation dans la sortie.

Production attendue

 OriginId DestinationId DestinationName TotalJourneyTime 1 1 Destination 1 10 2 3 Destination 3 40 

Utilisez un RANK pour classr chaque voyage divisé par l'origine et la destination et ordonné par le time de trajet

 WITH RankedTravelTimes AS ( select originid, destinationId, totaljourneytime, rank() over (partition by originid,destinationid order by totaljourneytime ) as r from traveltimes ) SELECT rtt.*, d.name FROM RankedTravelTimes rtt INNER JOIN Destinations d ON rtt.destinationId = d.id WHERE rtt.r=1 

Ce qui précède comprendra à la fois le voyage de 1-2 et 2-2 en tant que séparé. Si vous êtes uniquement intéressé par la destination, vous pouvez retirer originId de la partition.

Je ne suis pas sûr de voir le problème ici avec simplement joindre et regrouper datatables avec un MIN sur le time de trajet:

 CREATE TABLE #Traveltimes ( [OriginId] INT , [DestinationId] INT , [TotalJourneyTime] INT ); INSERT INTO #Traveltimes ( [OriginId], [DestinationId], [TotalJourneyTime] ) VALUES ( 1, 1, 10 ), ( 1, 2, 20 ), ( 2, 2, 30 ), ( 2, 3, 40 ), ( 2, 3, 50 ); CREATE TABLE #Destinations ( [DestinationId] INT , [Name] VARCHAR(13) ); INSERT INTO #Destinations ( [DestinationId], [Name] ) VALUES ( 1, 'Destination 1' ), ( 2, 'Destination 2' ), ( 3, 'Destination 3' ); SELECT d.DestinationId , d.Name , tt.OriginId , MIN(tt.TotalJourneyTime) MinTime FROM #Destinations d INNER JOIN #Traveltimes tt ON tt.DestinationId = d.DestinationId GROUP BY tt.OriginId , d.DestinationId , d.Name DROP TABLE #Destinations DROP TABLE #Traveltimes 

Vous donne:

 DestinationId Name OriginId MinTime 1 Destination 1 1 10 2 Destination 2 1 20 2 Destination 2 2 30 3 Destination 3 2 40 

Note: pourquoi voyagez-vous de la destination 1 à elle-même?

Je pense que vous voulez ce qui suit:

 ;with cte as(select *, row_number() over(partition by DestinationId order by TotalJourneyTime) rn from TravelTimes) select * from cte c join Destinations d on c.DestinationId = d.DestinationId where c.rn = 1