Mysql SELECT distinct由Group by和Order by

时间:2015-05-28 09:18:57

标签: mysql group-by sql-order-by

我的SQL SELECT语句有问题。我得到了正确的顺序,正确的驱动程序,但我的其他列不正确!我无法正确地做到这一点。

我有这样的数据:

id,     races_id,   drivers_id,     drive_nr,   lap_nr,     time,           dnf
"231",  "9",        "41",           "1",        "1",        "00:00:04.750", "0"
"232",  "9",        "41",           "1",        "2",        "00:00:06.030", "0"
"233",  "9",        "41",           "1",        "3",        "00:00:01.740", "0"
"234",  "9",        "42",           "1",        "1",        "00:00:05.440", "0"
"235",  "9",        "42",           "1",        "2",        "00:00:05.400", "0"
"236",  "9",        "42",           "1",        "3",        "00:00:02.300", "0"
"237",  "9",        "43",           "1",        "1",        "00:00:00.620", "0"
"238",  "9",        "43",           "1",        "2",        "00:00:00.290", "0"
"239",  "9",        "43",           "1",        "3",        "00:00:00.280", "0"
"240",  "9",        "44",           "1",        "1",        "00:00:00.600", "0"
"241",  "9",        "44",           "1",        "2",        "00:00:00.190", "0"
"242",  "9",        "44",           "1",        "3",        "00:00:00.220", "0"
"243",  "9",        "45",           "1",        "1",        "00:00:02.830", "0"
"244",  "9",        "45",           "1",        "2",        "00:00:01.890", "0"
"245",  "9",        "45",           "1",        "3",        "00:00:03.200", "0"
"246",  "9",        "46",           "1",        "1",        "00:00:03.580", "0"
"247",  "9",        "46",           "1",        "2",        "00:00:04.550", "0"
"248",  "9",        "46",           "1",        "3",        "00:00:01.060", "0"
"249",  "9",        "47",           "1",        "1",        "00:00:02.920", "0"
"250",  "9",        "47",           "1",        "2",        "00:00:03.950", "0"
"251",  "9",        "47",           "1",        "3",        "00:00:00.320", "0"
"252",  "9",        "48",           "1",        "1",        "00:00:02.150", "0"
"253",  "9",        "48",           "1",        "2",        "00:00:05.720", "0"
"254",  "9",        "48",           "1",        "3",        "00:00:04.530", "0"
"255",  "9",        "49",           "1",        "1",        "00:00:01.530", "0"
"256",  "9",        "49",           "1",        "2",        "00:00:04.360", "0"
"257",  "9",        "49",           "1",        "3",        "00:00:07.110", "0"
"258",  "9",        "50",           "1",        "1",        "00:00:00.450", "0"
"259",  "9",        "50",           "1",        "2",        "00:00:03.550", "0"
"260",  "9",        "50",           "1",        "3",        "00:00:07.900", "0"

查询:

SELECT  `id` ,  
    `races_id` ,  
    `drivers_id` ,  
    `drive_nr` ,  
    `lap_nr` , 
    MIN( `time` ) AS TIME,  
    `dnf` 
FROM  `laps` 
WHERE  `races_id` =9 
GROUP BY  drivers_id` 
ORDER BY MIN(  `time` ) ASC 

我明白了:

id,     races_id,   drivers_id,     drive_nr,   lap_nr,     time,           dnf
240,    9,          44,             1,          1,          00:00:00.190,   0
237,    9,          43,             1,          1,          00:00:00.280,   0
249,    9,          47,             1,          1,          00:00:00.320,   0
258,    9,          50,             1,          1,          00:00:00.450,   0
246,    9,          46,             1,          1,          00:00:01.060,   0
255,    9,          49,             1,          1,          00:00:01.530,   0
231,    9,          41,             1,          1,          00:00:01.740,   0
243,    9,          45,             1,          1,          00:00:01.890,   0
252,    9,          48,             1,          1,          00:00:02.150,   0
234,    9,          42,             1,          1,          00:00:02.300,   0

所以我按照正确的顺序获得了正确的时间列,但没有像ID, drive_nr, lap_nr, dnf

这样的其他列

如何修复我的查询以获得具有正确其他数据的最短时间的不同drivers_id?

2 个答案:

答案 0 :(得分:0)

如果您删除“GROUP BY”

SELECT  `id` ,  `races_id` ,  `drivers_id` ,  `drive_nr` ,  `lap_nr` , MIN( `time` ) AS TIME,  `dnf` FROM  `laps` WHERE  `races_id` = 9 ORDER BY MIN(  `time` ) ASC

Take a look on this link, use of group by and min

答案 1 :(得分:0)

问题在于GROUP BY将行组合在一起以形成聚合函数。在标准SQL中,返回的每个列必须是group by子句或聚合字段中提到的,但是MySQL扩展了它。

但是,虽然MySQL确实允许返回额外的列,但它没有指定这些列的值来自哪一行。虽然有一种模式(似乎是我认为插入的最后一行),但这没有定义,可能会改变。

要获得其他字段,您有几个选择。

最简单的是有一个子查询获取驱动程序ID和该驱动程序ID的一圈的最小时间,然后将其连接到laps表(加入驱动程序ID和时间)top获取值匹配行的其他字段。这有几个小的缺点。首先,MySQL不会在子查询的字段上使用索引来连接到主表,但是数据有限可能不是问题(超出了在慢查询日志中弹出的查询的烦恼)。第二个问题是如果有人在两圈之间分享最佳单圈时间。

sql的简单示例: -

SELECT a.id,  
    a.races_id,  
    a.drivers_id,  
    a.drive_nr,  
    a.lap_nr, 
    mt.min_time,
    a.dnf 
FROM laps a
INNER JOIN
(
    SELECT  drivers_id ,  
        MIN( `time` ) AS min_time
    FROM  laps 
    WHERE  races_id = 9 
    GROUP BY  drivers_id 
) mt
ON a.drivers_id = mt.drivers_id
AND a.`time` = mt.min_time
WHERE  a.races_id = 9 
ORDER BY min_time ASC 

如果你有相同的最小单圈时间的2圈,那么你需要指定返回哪些细节(或者你可能不关心,并且可能只是在外部查询上滥用GROUP BY)。

第二种解决方案是,您可以根据驱动程序ID和单圈时间为结果生成每行的序列号,并在更改驱动程序ID时重置序列号。然后丢弃没有1序列的任何一圈。但是当你有大量数据时,读取更难,并且可能非常慢。

示例如下(未测试): -

SELECT id,  
        races_id,  
        drivers_id,  
        drive_nr,  
        lap_nr, 
        `time`,
        dnf
FROM
(
    SELECT id,  
            races_id,  
            drivers_id,  
            drive_nr,  
            lap_nr, 
            `time`,
            dnf,
            @ctr := IF(drivers_id = @did, @ctr + 1, 1) AS ctr,
            @did := drivers_id
    FROM
    (
        SELECT id,  
                races_id,  
                drivers_id,  
                drive_nr,  
                lap_nr, 
                `time`,
                dnf 
        FROM laps 
        WHERE  races_id = 9
        ORDER BY drivers_id, `time`
    )
    CROSS JOIN
    (
        SELECT @ctr := 0, @did := 0
    ) sub1
) sub2
WHERE ctr = 1
ORDER BY `time`