SQL Group By and min (MySQL)

前端 未结 3 1777
挽巷
挽巷 2020-12-07 01:41

I have the following SQL:

select code, distance from places;    

The output is below:

CODE    DISTANCE            LOCATION
         


        
相关标签:
3条回答
  • 2020-12-07 02:26

    You can try to do a nested lookup between the minimum grouping and the original table.

    This seems to do the trick

    SELECT MinPlaces.Code, MinPlaces.Distance, Places.Location 
    FROM Places INNER JOIN
    (
        SELECT Code, MIN(Distance) AS Distance
        FROM Places
        GROUP BY Code
        HAVING MIN(Distance) > 0 
    ) AS MinPlaces ON Places.Code = MinPlaces.Code AND Places.Distance = MinPlaces.Distance
    ORDER BY MinPlaces.Distance ASC
    

    UPDATE: Tested using the following:

    DECLARE @Places TABLE ( Code INT, Distance FLOAT, Location VARCHAR(50) )
    
    INSERT INTO @Places (Code, Distance, Location)
    VALUES
    (106, 386.895834130068, 'New York, NY'),
    (80, 2116.6747774121, 'Washington, DC'),
    (80, 2117.61925131453, 'Alexandria, VA'),
    (106, 2563.46708627407, 'Charlotte, NC')
    
    SELECT MinPlaces.Code, MinPlaces.Distance, P.Location 
    FROM @Places P INNER JOIN
    (
        SELECT Code, MIN(Distance) AS Distance
        FROM @Places
        GROUP BY Code
        HAVING MIN(Distance) > 0 
    ) AS MinPlaces ON P.Code = MinPlaces.Code AND P.Distance = MinPlaces.Distance
    ORDER BY MinPlaces.Distance ASC
    

    And this yields:

    enter image description here

    0 讨论(0)
  • 2020-12-07 02:29

    To get the correct associated location, you'll need to join a subselect which gets the minimum distance per code on the condition that the distance in the outer main table matches with the minimum distance derived in the subselect.

    SELECT a.code, a.distance
    FROM   places a
    INNER JOIN
    (
        SELECT   code, MIN(distance) AS mindistance
        FROM     places
        GROUP BY code
    ) b ON a.code = b.code AND a.distance = b.mindistance
    ORDER BY a.distance
    
    0 讨论(0)
  • 2020-12-07 02:30

    You did not say your DBMS. The following solutions are for SQL Server.

    WITH D AS (
       SELECT code, distance, location,
          Row_Number() OVER (PARTITION BY code ORDER BY distance) Seq
       FROM places
    )
    SELECT *
    FROM D
    WHERE Seq = 1
    

    If you have a table with unique Codes, and an index in your Places table on [Code, Distance] then a CROSS APPLY solution could be better:

    SELECT
       X.*
    FROM
       Codes C
       CROSS APPLY (
          SELECT TOP 1 *
          FROM Places P
          WHERE C.Code = P.Code
          ORDER BY P.Distance
       ) X
    

    I cannot work on a solution for mysql unti much later.

    P.S. You cannot rely on insertion order. Do not try!

    0 讨论(0)
提交回复
热议问题