Cross适用于根据DateTime获取特定记录

时间:2015-07-09 03:34:57

标签: sql sql-server sql-server-2012

以下是针对以下场景的sql小提琴:http://sqlfiddle.com/#!6/434fc/1

基准表:

╔═══════════════════════╗
║ Id   DateTime         ║
╠═══════════════════════╣
║ 201  2015-05-03 08:01 ║
║ 301  2015-05-03 08:20 ║
║ 401  2015-05-03 08:40 ║
╚═══════════════════════╝

将表格提取为E:

╔═══════════════════════════════════════╗
║     Id   DateTime            Location ║
╠═══════════════════════════════════════╣
║     201  2015-05-03 07:50    City A   ║
║     201  2015-05-03 08:01    City B   ║
║     201  2015-05-03 08:50    City C   ║
║     301  2015-05-03 07:15    City E   ║
║     301  2015-05-03 08:01    City F   ║
║     301  2015-05-03 08:20    City G   ║
║     401  2015-05-03 07:15    City W   ║
║     401  2015-05-03 08:30    City X   ║
║     401  2015-05-03 08:55    City Y   ║
║     401  2015-05-03 09:00    City Z   ║
╚═══════════════════════════════════════╝

期望的结果:

╔══════════════════════════════════════╗
║     Location  Id    DateTime         ║
╠══════════════════════════════════════╣
║     City B    201   2015-05-03 08:01 ║
║     City G    301   2015-05-03 08:20 ║
║     City X    401   2015-05-03 08:30 ║
╚══════════════════════════════════════╝

使用以下代码,我得到ID 201和301的正确结果,但对于401,我需要Extract表中第一个最大日期,该日期小于Base中的日期} table,因为Extract表中没有与Base表中的匹配日期。

select ca.Location, B.id, ca.Datetime
from Base B
cross apply(select top 1 Location, DateTime
       from Extract E 
       where B.id = E.id 
       order by case when B.DateTime = E.DateTime then 1 else 0 end desc,
                     E.Datetime)ca

请帮助编辑此代码以获得所需的结果。非常感谢你。

1 个答案:

答案 0 :(得分:1)

你快到了。我调整了您的SQL Fiddle

select ca.Location, B.id, ca.Datetime
from 
    Base B
    cross apply
    (
        select top (1) E.Location, E.DateTime
        from Extract E 
        where 
            B.id = E.id
            AND B.DateTime >= E.DateTime
        order by E.Datetime DESC
    ) AS CA

请注意,如果某个ID Extract表的日期不小于或等于Base日期,则根本不会返回此ID。如果您确实希望查看Base表中的每一行,无论Extract表中的内容是什么,请使用OUTER APPLY代替CROSS APPLY。您将获得LocationDateTime的NULL,但所有ID都会在那里。