从SQL中选择最佳结果

时间:2011-10-19 13:04:48

标签: mysql sql greatest-n-per-group

这是一个简单的问题,但我似乎无法解决它。

我想从表中选择最新的结果,并将其与另一个表中的单个元素连接起来。

为了更好,这是一个简单的架构:

Table 1 - Person
personId -PK - INT - AUTO ID
name - VARCHAR

Table 2 - Event
eventId - PK - INT - AUTO ID
personId - FK
timestamp  - DATETIME
event - ENUM ('Went Out', 'Came back')

我想做的是返回所有人的列表以及每个人执行的最新动作

示例结果:

  

名称| personId |时间戳| eventId |事件

     鲍勃| 1 | 2011-08-7 3 | '走出去'

我做了一个简单的查询,加入了两个表,然后按personId创建了一个组,并按时间戳排序,但返回的结果始终是该人的第一个操作,而不是他们的最新操作。

任何想法?

5 个答案:

答案 0 :(得分:3)

SELECT p.name, p.personId, e.timestamp, e.eventId, e.event
FROM person p
  INNER JOIN Event e 
    ON e.eventId = 
      ( SELECT MAX(eventId)
        FROM Event 
        WHERE personId = p.personId 
        GROUP BY personId 
        LIMIT 1 )

OR

SELECT p.Name, p.ID, me.timestamp, me.ID, me.event
FROM person p
INNER JOIN (
            SELECT id, timestamp, event
            FROM Event 
            WHERE personId = p.ID               
            ORDER BY timestamp DESC LIMIT 1
           ) me
ON p.ID = me.id

PS:抱歉,但现在无法测试这两个查询

答案 1 :(得分:3)

SELECT 
  t1.Name,
  t1.PersonId,
  t2.TimeStamp,
  t2.EventId,
  t2.Event
FROM Table1 t1
INNER JOIN Table2 t2 ON t2.PersonId = t1.PersonID
INNER JOIN (SELECT
              PersonId,
              MAX(TimeStamp) as LastEventDateTime
            FROM Table2 
            GROUP BY PersonID) LE 
  ON LE.PersonID = t2.PersonID 
    AND LE.LastEventDateTime = t2.TimeStamp

答案 2 :(得分:0)

你想做一个

ORDER by `timestamp` DESC

(desc from descending)获取最高时间戳值而不是最低值

答案 3 :(得分:0)

ANSI标准方式是:

select name, personid, timestamp, eventid, event
from person
join event on event.personid=person.personid
  and event.timestamp=(select max(timestamp) from event e2
                       where e2.personid=person.personid)

我有一段时间没有使用MySQL而且我没有安装方便,但你可能会得到你想要的东西:

select name, personid, timestamp, eventid, event
from person
join event on event.personid=person.personid
group by personid
order by personid, timestamp desc

这是非标准的,因为按照标准,select中的任何内容都必须在group-by中或者是一个聚合,而在这里我们也不想这样做。但是我记得MySQL不需要这样做,所以我给它一个旋转,看看会发生什么。

答案 4 :(得分:0)

使用覆盖密钥的替代解决方案假定order by Id将产生与order by timestamp相同的结果

SELECT p.Name, p.ID, me.timestamp, me.ID, me.event
FROM person p
JOIN (
      SELECT personId, MAX(ID) id 
      FROM Event 
      WHERE personId = p.ID               
      GROUP BY personId
     ) me
ON p.ID = me.id

Order by timestamp更自然,可能更安全,但速度更快。