SQL:如何在只有任何“类型”中的“最大”项的情况下进行联接查询?
我有两个表:表事件类型和具有一对多关系的表事件。每个事件都有一个时间戳。现在,我希望有一个SQL查询,它返回每个eventtype+其对应的事件以及最新的时间戳,我可以保证在这种情况下是唯一的 我不完全确定如何以正确的方式直接使用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
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对不起,我要走了/