来自MySQL的奇怪查询结果

时间:2013-07-26 10:10:53

标签: mysql

我有一个查询,我正在我的数据库上测试,但由于一些奇怪的原因,并随机,它返回一组不同的结果。有趣的是,从数千行返回的结果集只有两个不同的结果集,查询将随机返回一个或另一个,但没有别的。

查询是否只返回两个数据集中的一个?查询和架构如下。

我的目标是在给定时间段内为给定音轨选择最快圈速,但每个用户只选择最快圈数(因此前10名中总共有10个不同用户)。

大多数情况下返回正确的结果,但随机返回一个完全不同的结果集。

SELECT `lap`.`ID`, `lap`.`qualificationTime`, `lap`.`userId` 
FROM `lap` 
WHERE (lap.trackID =4)
AND (lap.raceDateTime >=  "2013-07-25 10:00:00")
AND (lap.raceDateTime <  "2013-08-04 23:59:59")
AND (isTestLap =0)
GROUP BY  `userId` 
ORDER BY  `qualificationTime` ASC 
LIMIT 10

架构:

CREATE TABLE IF NOT EXISTS `lap` (
    `ID` int(11) NOT NULL AUTO_INCREMENT,
    `userId` int(11) DEFAULT NULL,
    `trackId` int(11) DEFAULT NULL,
    `raceDateTime` datetime NOT NULL,
    `qualificationTime` decimal(7,4) DEFAULT '0.0000',
    `isTestLap` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`)

(数据库创建脚本修剪了不需要的列)

5 个答案:

答案 0 :(得分:1)

您选择的是lap.IDlap.qualificationTimelap.userId,但您不是GROUPing BY他们。您可以选择您分组的字段,或者在其他字段上汇总函数(MINMAXAVG等)。否则,结果未定义。

答案 1 :(得分:1)

您正在使用称为隐藏列的MySQL(错误)功能。正如其他人所指出的那样,您可以在select语句中放置不在group by中的列。但是,返回的值是任意的,甚至不能保证从一次运行到下一次运行是相同的。

解决方案是找到每个用户的最长资格时间。然后加入此信息以获取其他字段。这是一种方式:

select l.*
from (SELECT userId, min(qualificationtime) as minqf
      FROM lap
      WHERE (lap.trackID =4)
      AND (lap.raceDateTime >=  "2013-07-25 10:00:00")
      AND (lap.raceDateTime <  "2013-08-04 23:59:59")
      AND (isTestLap =0)
      GROUP BY  `userId` 
     ) lu join
     lap l
     on lu.minqf = l.qualificationtime
ORDER BY  l.`qualificationTime` ASC 
LIMIT 10

答案 2 :(得分:0)

我认为您的意思是有时lapIDlapqualificationTime的值不同。这对mysql来说是正确的行为。因为您按userId进行分组,并且您不知道将返回其他字段的值。 Mysql可以根据第一个值或最后一行读取选择不同的值。

答案 3 :(得分:0)

它可能是您在十进制实体上的ORDER BY,以及DB如何存储它然后检索它。你能分享两种不同的结果吗?

答案 4 :(得分:0)

我会检查这样的事情:

   SELECT  `l1`.`qualificationTime`, `l1`.`userId`,
          (SELECT l2.ID FROM `lap` AS l2 WHERE l2.`userId` = l1.userId AND 
          l2.qualificationTime = min(l1.`qualificationTime`))
   FROM `lap` AS `l1`
   WHERE (l1.trackID =4)
          AND (l1.raceDateTime >=  "2013-07-25 10:00:00")
          AND (l1.raceDateTime <  "2013-08-04 23:59:59")
          AND (isTestLap =0)
   GROUP BY  `userId`
   ORDER BY  `qualificationTime` ASC
   LIMIT 10