SQL:如何在只有任何“类型”中的“最大”项的情况下进行联接查询?

SQL:如何在只有任何“类型”中的“最大”项的情况下进行联接查询?,sql,join,group-by,greatest-n-per-group,Sql,Join,Group By,Greatest N Per Group,我有两个表:表事件类型和具有一对多关系的表事件。每个事件都有一个时间戳。现在,我希望有一个SQL查询,它返回每个eventtype+其对应的事件以及最新的时间戳,我可以保证在这种情况下是唯一的 我不完全确定如何以正确的方式直接使用SQL完成这项工作。到目前为止,我使用了类似的方法: select * from eventtypes left join ( select events.* from events right join ( select max(t

我有两个表:表事件类型和具有一对多关系的表事件。每个事件都有一个时间戳。现在,我希望有一个SQL查询,它返回每个eventtype+其对应的事件以及最新的时间戳,我可以保证在这种情况下是唯一的

我不完全确定如何以正确的方式直接使用SQL完成这项工作。到目前为止,我使用了类似的方法:

select * from eventtypes left join 
(
    select events.* from events right join 
    (
        select max(timestamp) as maxtimestamp from events groupby eventtypeid
    ) maxtimestamps
    on events.timestamp = maxtimestamps.maxtimestamp
) lastevents
on eventtypes.id = lastevents.eventtypeid
select max(timestamp), corresponding(id), corresponding(name), ... 
from events groupby eventtypeid
对不起,打扰一下。这不是生产,我只是在脑子里写的 这两个内在的选择总是让我怀疑这是否是正确的方法。我一直在想,应该有这样的事情:

select * from eventtypes left join 
(
    select events.* from events right join 
    (
        select max(timestamp) as maxtimestamp from events groupby eventtypeid
    ) maxtimestamps
    on events.timestamp = maxtimestamps.maxtimestamp
) lastevents
on eventtypes.id = lastevents.eventtypeid
select max(timestamp), corresponding(id), corresponding(name), ... 
from events groupby eventtypeid

我认为类似于对应的函数是不存在的。为什么?在sql server中,这难道不可能比执行2个选择和连接更快地实现吗?或者在sql中是否有其他方法可以有效地实现这一点?或者它已经很有效了?

您的查询可以简化为:

select 
      eventtypes.*,
      events.*
from 
    eventtypes 
  left join 
      events 
    join 
      (
          select
                eventtypeid,                             --- this line added 
                max(timestamp) as maxtimestamp 
          from events 
          group by eventtypeid
      ) maxtimestamps
    on  events.timestamp = maxtimestamps.maxtimestamp
    AND events.eventtypeid = maxtimestamps.eventtypeid   --- and this
  on eventtypes.id = lastevents.eventtypeid
添加这些行是因为如果时间戳不唯一,您的版本可能会显示不正确的结果

在许多DBMS中,有一些称为分析或窗口的函数,它们可以按照您描述的方式获得相同的结果:

SELECT
      et.*,
      e.*
FROM eventtypes et
  LEFT JOIN
    ( SELECT 
            events.*,
            ROW_NUMBER() OVER(PARTITION BY eventtypeid 
                              ORDER BY timestamp DESC )
              AS RowNum
      FROM events
    ) e
    ON e.eventtypeid = et.eventtypeid
    AND e.RowNum = 1

由于时间戳保证是唯一的,并且只有在该时间戳为唯一时,此查询才会执行以下操作:

select 
      eventtypes.*,
      events.*
from 
    events A INNER JOIN eventtypes B ON A.eventtypeid=b.id
WHERE 
    A.timestamp IN (SELECT MAX(timestamp) FROM events GROUP BY eventtypeid)

啊。我的内心选择有一个错误。你直接做到了我的意思,所以我也更正了我的帖子。除此之外,我的问题的关键是这是一个群体的事情。使用理论上的对应函数,您的查询只能用一个select by do select eventtypes.*、maxevents.timestamp、correspondingevents.*从eventtypes开始在{您做了什么}eventtypes groupby events.id上加入事件,因为我认为对应的函数不存在,我错了吗?,你写的东西实际上是用SQL进行查询的思维方式吗?起初我以为你有一个bug,没有添加这两行,但由于时间戳保证是唯一的,所以这两行不是必需的。@Tomek:如果timestmap是唯一的,可以省略它们。但我更喜欢这两种情况。如果将来删除唯一约束,它将起作用;其次,它将仅为Group By和JOIN使用一个索引:eventtypeid,timestamp。@ypercube:完全同意,如果将来可能违反约束,则您的查询将被取消safer@you两者,如果你不加上这两行,它需要多于1个索引吗?您的意思是选择A.*,B.*。。。但是是的,那也行!嗯,很有趣。类似的东西是否也可以工作:其中A.timestamp、A.id在selectmaxtimstamp中,eventtypeid由eventtypeid从events组中选择?或者有不同的语法吗?@marc40000:不,你不能在运算符2中使用columns@TOmek:如果我没有错的话,我想你可以在Postgres和DB2的一些DBMS中使用。它是有效的SQL语法,但在大多数DBMS中都没有实现。@ypercube:我是在MS SQL Server的上下文中思考的,但没有提到具体的引擎,所以是的,感谢回答者,我在该语句中实现了快速!这两个答案实际上都对我的问题有帮助,都说明了如何做到这一点,围绕它们的讨论也有帮助。所以很难从这两个答案中做出选择。我就选托梅克的,因为他的分数比较少D对不起,我要走了/