我有一个球员表现的表格:

CREATE TABLE TopTen (
  id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
  home INT UNSIGNED NOT NULL,
  `datetime`DATETIME NOT NULL,
  player VARCHAR(6) NOT NULL,
  resource INT NOT NULL
);

哪个查询将为每个不同的家庭返回包含其datetime最大值的行?换句话说,我如何通过最大datetime(按home分组)进行过滤,并在结果中仍然包括其他非分组、非聚合列(例如player) ?

对于这个示例数据:

INSERT INTO TopTen
  (id, home, `datetime`, player, resource)
VALUES
  (1, 10, '04/03/2009', 'john', 399),
  (2, 11, '04/03/2009', 'juliet', 244),
  (5, 12, '04/03/2009', 'borat', 555),
  (3, 10, '03/03/2009', 'john', 300),
  (4, 11, '03/03/2009', 'juliet', 200),
  (6, 12, '03/03/2009', 'borat', 500),
  (7, 13, '24/12/2008', 'borat', 600),
  (8, 13, '01/01/2009', 'borat', 700)
;

结果应该是:

id home datetime player resource
1 10 04/03/2009 john 399
2 11 04/03/2009 juliet 244
5 12 04/03/2009 borat 555
8 13 01/01/2009 borat 700

我尝试了一个子查询获得每个家庭的最大日期时间:

-- 1 ..by the MySQL manual: 

SELECT DISTINCT
  home,
  id,
  datetime AS dt,
  player,
  resource
FROM TopTen t1
WHERE `datetime` = (SELECT
  MAX(t2.datetime)
FROM TopTen t2
GROUP BY home)
GROUP BY `datetime`
ORDER BY `datetime` DESC

结果集有130行,但数据库有187行,这表明结果包括home的一些副本。

然后我尝试连接到一个子查询,为每个行id获得最大日期时间:

-- 2 ..join

SELECT
  s1.id,
  s1.home,
  s1.datetime,
  s1.player,
  s1.resource
FROM TopTen s1
JOIN (SELECT
  id,
  MAX(`datetime`) AS dt
FROM TopTen
GROUP BY id) AS s2
  ON s1.id = s2.id
ORDER BY `datetime`

没有。给出所有的记录。

我尝试了各种奇特的查询,每一个都有不同的结果,但没有一个能让我更接近解决这个问题。


当前回答

我想这会给你想要的结果:

SELECT   home, MAX(datetime)
FROM     my_table
GROUP BY home

但如果你也需要其他列,只需与原始表进行连接(检查Michael La Voie的答案)

致以最亲切的问候。

其他回答

你太接近了!你所需要做的就是同时选择home和它的最大日期时间,然后在这两个字段上连接到topten表:

SELECT tt.*
FROM topten tt
INNER JOIN
    (SELECT home, MAX(datetime) AS MaxDateTime
    FROM topten
    GROUP BY home) groupedtt 
ON tt.home = groupedtt.home 
AND tt.datetime = groupedtt.MaxDateTime

这将工作,即使你有两行或更多的每个家庭具有相等的DATETIME:

SELECT id, home, datetime, player, resource
FROM   (
       SELECT (
              SELECT  id
              FROM    topten ti
              WHERE   ti.home = t1.home
              ORDER BY
                      ti.datetime DESC
              LIMIT 1
              ) lid
       FROM   (
              SELECT  DISTINCT home
              FROM    topten
              ) t1
       ) ro, topten t2
WHERE  t2.id = ro.lid

我想这会给你想要的结果:

SELECT   home, MAX(datetime)
FROM     my_table
GROUP BY home

但如果你也需要其他列,只需与原始表进行连接(检查Michael La Voie的答案)

致以最亲切的问候。

因为人们似乎一直在遇到这个问题(评论日期从1.5年不等),这并不简单:

SELECT * FROM (SELECT * FROM topten ORDER BY datetime DESC) tmp GROUP BY home

不需要聚合函数…

欢呼。

这可以在SQLServer中工作,并且是我所见过的唯一不需要子查询或cte的解决方案-我认为这是解决这类问题的最优雅的方法。

  SELECT TOP 1 WITH TIES *
    FROM TopTen
ORDER BY ROW_NUMBER() OVER (PARTITION BY home
                                ORDER BY [datetime] DESC)

在ORDER BY子句中,它使用窗口函数根据ROW_NUMBER生成并排序-为每个[home]的最高[datetime]分配1值。

SELECT TOP 1 WITH TIES将选择ROW_NUMBER最低的一条记录(将为1),以及所有ROW_NUMBER相同的记录(也是1)

因此,您将检索每个排名第一的记录的所有数据——也就是说,具有最高[datetime]值的记录的所有数据及其给定的[home]值。