SQL:加入和排序后的第一行组

时间:2015-12-03 13:46:49

标签: sql sql-server

假设我们有两张下表:

走时

    @Override
public void onConnected(Bundle connectionHint) {
    super.onConnected(connectionHint);
    // create new contents resource
    Drive.DriveApi.newDriveContents(getGoogleApiClient())
            .setResultCallback(driveContentsCallback);
}

final private ResultCallback<DriveContentsResult> driveContentsCallback = new
        ResultCallback<DriveContentsResult>() {
            @Override
            public void onResult(DriveContentsResult result) {
                if (!result.getStatus().isSuccess()) {
                    showMessage("Error while trying to create new file contents");
                    return;
                }
                final DriveContents driveContents = result.getDriveContents();

                // Perform I/O off the UI thread.
                new Thread() {
                    @Override
                    public void run() {
                        // write content to DriveContents
                        OutputStream outputStream = driveContents.getOutputStream();
                        Writer writer = new OutputStreamWriter(outputStream);
                        try {
                            writer.write("Hello World!");
                            writer.write("Hello World!");
                            writer.close();
                        } catch (IOException e) {
                            Log.e(TAG, e.getMessage());
                        }

                        MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                                .setTitle("Orders")
                                .setMimeType("application/vnd.google-apps.spreadsheet")
                                .setStarred(true).build();



                        // create a file on root folder
                        Drive.DriveApi.getRootFolder(getGoogleApiClient())
                                .createFile(getGoogleApiClient(), changeSet, driveContents)
                                .setResultCallback(fileCallback);
                    }
                }.start();
            }
        };

final private ResultCallback<DriveFileResult> fileCallback = new
        ResultCallback<DriveFileResult>() {
            @Override
            public void onResult(DriveFileResult result) {
                if (!result.getStatus().isSuccess()) {
                    showMessage("Error while trying to create the file");
                    return;
                }
                showMessage("Created a file with content: " + result.getDriveFile().getDriveId());
                storeId(result.getDriveFile().getDriveId());
                kill_activity();
            }
        };v

目的地

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

如何找到每个出发地和目的地之间最快的旅程? 我想通过DestinationId加入TravelTimes和Destinations,然后按OriginId对它们进行分组,并按TotalJourneyTime对每个组进行排序,并选择每组的第一行。
我确实尝试过加入和分组,但似乎group by不是我案例的解决方案,因为我在输出中没有任何聚合列。

预期输出

DestinationId           Name
      1               Destination 1
      2               Destination 2
      3               Destination 3

3 个答案:

答案 0 :(得分:4)

使用RANK对按出发地和目的地划分的每个旅程进行排名,并按行程时间排序

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

以上将包括1-2和2-2之间的旅程。如果您只对目标感兴趣,可以从分区中删除originId

答案 1 :(得分:2)

我不确定此处是否只是在旅程时使用MIN加入和分组数据时会发现问题:

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

给你:

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

注意:你为什么要从目的地1前往自己?

答案 2 :(得分:1)

我想你想要以下内容:

;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