7

我在这里看到了类似类型的问题,但没有一个对我的情况有所帮助。

我有一张表可以说测试(使用 mysql MyISAM)

测试具有以下架构:

    TID INT PRIMARY KEY AUTO_INCREMENT
    TData varchar (data that i want to select)
    TUserID INT (this will be joined with users table, same users can have many records here)
    TViewedAt DATETIME (records each time user visits page, datetime format)

现在,每次当前登录的用户访问测试页面时,它都会在此表中添加记录,记录访问者的用户 ID,用户访问的一些数据和日期和时间,每次都会自动递增 TID。

然后我有一个后端管理页面,我可以在其中查看哪个用户访问了测试页面,访问了多少次,数据和时间。基本上它是一个包含 20-25 个最新行列表的表格。我的查询应该只为每个数据选择一条记录。用户的数据可以相同,但时间不同,但我只想为每个用户选择一个最新的数据。因此,如果用户访问测试页面 10 次,则有 10 条记录进入数据库,但表中仅显示 1 条最新记录。如果另一个用户访问页面 15 次,它会显示第二个用户的 1 条记录,这又是最新的,所以现在我们总共有 2 行显示在表格上。我让一切正常工作,但出于某种原因 GROUP BY 并且 MAX(date) 没有给我每个日期的最新日期时间。

这是我的查询:

   SELECT *
   FROM Test
   WHERE TUserID = 123
   GROUP BY TData
   ORDER BY TViewedAt

返回 2 行,其中所有行都不是最新的。

多谢

4

4 回答 4

15

我认为通过以下方式可以实现您所需要的,这些操作就是所谓的“分组最大值”。

选项1

这是最容易理解的,子查询将返回TID所有用户的最大值,因为它与我们max一起使用,Group By而不是我们执行其他查询来获取这些 ID 的所有数据。

 Select TID, TData, TUserID, TViewedAt
 From Test 
 Where TID In(
    Select Max(TID)
    From Test
    Group By TUserID
)

选项 2

理解起来稍微复杂一些,但很可能更有效,这是基于当t1.TViewedAt处于最大值时,没有t2.TViewedAt更大的值并且 t2 行值将是NULL

SELECT t1.TID, t1.TData, t1.TUserID, t1.TViewedAt
FROM Test t1
LEFT JOIN Test t2 ON t1.TUserID = t2.TUserID AND t1.TViewedAt < t2.TViewedAt
WHERE t2.TUserID IS NULL;

结果

TID TData   TUserID   TViewedAt
4   test3   123       2012-10-05 00:00:00.000
5   test2   213       2012-10-03 00:00:00.000
于 2012-10-05T19:05:30.710 回答
1

您需要GROUP BY TUserID最大聚合。

SELECT
  TID,
  TData,
  main.TUserID
  main.TViewedAt
FROM
  yourTable main
  JOIN ( 
    SELECT TUserID, MAX(TViewedAt) AS TViewedAT FROM yourTable GROUP BY TUserID
  ) tmax ON main.TUserID = tmax.TUserID AND main.TViewedAt = tmax.TViewedAt

这是一种结合子查询的可移植方法。子查询提取TUserID,TViewedAt每个用户的最新信息,并将其与主表结合起来以提取TData匹配项。

如果您一次只需要一个用户,您可以执行以下操作:

SELECT 
  TData,
  TViewedAt
FROM yourTable
WHERE TUserID = 'someid'
GROUP BY TUserId
HAVING TViewedAt = MAX(TViewedAt)

上面的内容只能按照我编写的方式在 MySQL 中工作。其他 RDBMS 会抱怨TData出现在SELECT列表中但不在GROUP BY.

于 2012-10-05T18:59:56.967 回答
1

以下查询,可能对您有所帮助-

select * from pages where date(create_date)=(select date(create_date) from pages order by create_date limit 1)
于 2014-03-28T13:53:54.510 回答
0
SELECT t1.TData, t1.TUserID, t1.TViewedAt 
FROM Test t1
JOIN
(SELECT TUserID, MAX(TViewedAt)
FROM Test
GROUP BY TUserID) t2
ON t1.TUserID = t2.TUserID AND t1.TViewedAt=t2.TViewedAt
于 2012-10-05T19:01:28.747 回答