MySQL查询返回意外结果

时间:2012-03-15 03:55:39

标签: mysql sql

我有2张桌子,一张包含一个城市(在游戏中)的信息,另一张包含在整个一天中记录的分数。表格示例已经简化。

CREATE TABLE cities(
  cid INT(100),
  name VARCHAR(100),
  updatedAt DATETIME
);
CREATE TABLE cl_scores(
  cid INT(100),
  score INT(255),
  updatedAt DATETIME
);

我试图收集特定城市的分数列表。该列表应仅包含每天的MAX(updatedAt)日期和分数。以下是我到目前为止的情况:

SELECT a.cid, b.name, a.score, a.updatedAt FROM ci_scores AS a 
JOIN cities AS b ON a.cid = b.cid 
JOIN (SELECT MAX(updatedAt) AS maxUpdatedAt FROM ci_scores 
GROUP BY DATE(updatedAt)) AS L ON DATE(L.maxUpdatedAt) = DATE(a.updatedAt) 
WHERE a.cid = 10158241 ORDER BY a.updatedAt ASC;

但是,它并不是每天都会返回一个条目。它实际上是返回ci_scores表中的每一行,只需添加名称字段,如下所示:

+----------+---------+-------+---------------------+
| cid      | name    | score | updatedAt           |
+----------+---------+-------+---------------------+
| 10158241 | Genesis |  3087 | 2012-03-13 04:04:03 |
| 10158241 | Genesis |  3207 | 2012-03-13 17:48:56 |
| 10158241 | Genesis |  3255 | 2012-03-14 00:44:11 |
| 10158241 | Genesis |  3262 | 2012-03-14 10:21:05 |
| 10158241 | Genesis |  3262 | 2012-03-14 13:42:42 |
+----------+---------+-------+---------------------+

我在查询中做错了什么???

尝试解决方案

SELECT a.cid, b.name, a.score, a.updatedAt FROM ci_scores AS a 
JOIN cities AS b ON a.cid = b.cid 
JOIN (SELECT MAX(updatedAt) AS maxUpdatedAt FROM ci_scores 
GROUP BY DATE(updatedAt) LIMIT 1) AS L ON L.maxUpdatedAt = a.updatedAt
WHERE a.cid = 10158241 ORDER BY a.updatedAt ASC;

这不起作用,删除DATE()= DATE()会使它返回0条记录,因为时间不同。如果我将其添加回来,则返回:

+----------+---------+-------+---------------------+
| cid      | name    | score | updatedAt           |
+----------+---------+-------+---------------------+
| 10158241 | Genesis |  3087 | 2012-03-13 04:04:03 |
| 10158241 | Genesis |  3207 | 2012-03-13 17:48:56 |
+----------+---------+-------+---------------------+

这是不正确的,我每天需要1条记录,而该记录是当天输入的最新记录。

3 个答案:

答案 0 :(得分:2)

我认为您应该通过updateAT加入您的子集而不使用DATE函数

SELECT a.cid, b.name, a.score, a.updatedAt FROM ci_scores AS a 
JOIN cities AS b ON a.cid = b.cid 
JOIN (SELECT MAX(updatedAt) AS maxUpdatedAt FROM ci_scores 
GROUP BY DATE(updatedAt)) AS L ON L.maxUpdatedAt = a.updatedAt
WHERE a.cid = 10158241 ORDER BY a.updatedAt ASC;

<强>更新 在子查询中还有另一个错误,您需要按城市ID进行分组,以便获得正确的最大日期:

SELECT a.cid, b.name, a.score, a.updatedAt FROM ci_scores AS a 
JOIN cities AS b ON a.cid = b.cid 
JOIN (SELECT MAX(updatedAt), cid AS maxUpdatedAt FROM ci_scores 
GROUP BY DATE(updatedAt), cid) AS L ON L.maxUpdatedAt = a.updatedAt AND L.cid = a.cid
WHERE a.cid = 10158241 ORDER BY a.updatedAt ASC;

答案 1 :(得分:1)

SELECT a.cid, b.name, a.score, a.updatedAt FROM ci_scores AS a 
JOIN cities AS b ON a.cid = b.cid 
JOIN (SELECT MAX(updatedAt) AS maxUpdatedAt FROM ci_scores 
GROUP BY DATE(updatedAt) LIMIT 1) AS L ON L.maxUpdatedAt = a.updatedAt
WHERE a.cid = 10158241 ORDER BY a.updatedAt ASC;

答案 2 :(得分:0)

SELECT DISTINCT A.CID, C.NAME, A.updatedAt, A.SCORE FROM cl_scores A
INNER JOIN
(
SELECT D.CID, D.SD, MAX ( S.updatedAt ) MD FROM cl_scores S
INNER JOIN (SELECT DISTINCT S.CID, DATE ( S.updatedAt ) SD FROM cl_scores S WHERE S.CID = 10158241) D ON D.CID = S.CID AND D.SD = DATE ( S.updatedAt )
GROUP BY D.CID, D.SD
) B ON B.CID = A.CID AND B.MD = A.updatedAt
INNER JOIN cities C ON C.CID = A.CID

以上为您提供了CID = 10158241每天(表中只有几天!)行最大updatedAt及其各自的score ...请注意,如果您有两行与EXACT相同updatedAt(下至第二......)它可能会给你多行......