我有两张桌子,一张有日期(让我们称之为Table1) - 让我们说只有两个字段:
RecordID
DateTime
另一个(表2)是信息记录和日期时间,如下所示:
RecordID
DateTime
Info1
Info2
我需要以某种方式获取Table1.RecordID,其中该记录的DateTime和下一个记录之间有一些条目。
假设我们已经进入了表1
1, 01/01/2010
2, 01/02/2010
3, 01/03/2010
4, 01/04/2010
和表2
10, 10/02/2010
11, 11/02/2010
12, 15/04/2010
因此,对于这些记录,我想得到Table1的记录,其中Table2中的条目在记录的DateTime之后到下一个记录(或者如果它是Table1中的最后一个记录,那么表2中的记录见表1)。
有什么想法吗? :)
P.S - 我使用MSSQL
编辑:更多信息。
谢谢!
答案 0 :(得分:3)
如果table1中的RecordID是顺序的,没有间隙,这使我们的第一个任务更容易 - 我们需要从table1连接两行来表示我们感兴趣的时间跨度:
Table1 t1a
inner join
Table1 t1b
on
t1a.RecordID = t1b.RecordID - 1
除了我们需要处理没有另一行要加入的最后一行,所以我们需要改为left join
:
Table1 t1a
left join
Table1 t1b
on
t1a.RecordID = t1b.RecordID - 1
现在我们需要找出Table2中是否有适合此时间段的行。有两种明显的方法可以做到这一点 - 在where子句中进行EXISTS
检查,或者使用DISTINCT
进行额外的连接和过滤。哪一个更好地工作取决于许多因素,因此值得分析两者:
SELECT t1a.RecordID
FROM
Table1 t1a
left join
Table1 t1b
on
t1a.RecordID = t1b.RecordID - 1
where exists(select * from Table2 t2 where t2.DateTime >= t1a.DateTime and (t2.DateTime < t1b.DateTime or t1b.DateTime is null))
或:
SELECT DISTINCT t1a.RecordID
FROM
Table1 t1a
left join
Table1 t1b
on
t1a.RecordID = t1b.RecordID - 1
inner join
Table2 t2
on
t2.DateTime >= t1a.DateTime and
(t2.DateTime < t1b.DateTime or t1b.DateTime is null)
显然,可能需要调整大于和小于比较,这取决于我们构建的时间跨度的包容性或排他性上限和下限。
如果RecordID不是连续的,那么我们将转向搜索正确的行:
Table1 t1a
left join
Table1 t1b
on
t1a.DateTime < t1b.DateTime
left join
Table1 t1_nogap
on
t1a.DateTime < t1_nogap.DateTime and
t1_nogap.DateTime < t1b.DateTime
我们现在第三次引用Table1(t1_nogap),并尝试连接适合t1a和t1b找到的行之间的行。
那么我们在where子句中添加一个额外的条件,因为我们不想使用t1a和t1b中的timepans,我们在这里找到了这样一行:
SELECT DISTINCT t1a.RecordID
FROM
Table1 t1a
left join
Table1 t1b
on
t1a.DateTime < t1b.DateTime
left join
Table1 t1_nogap
on
t1a.DateTime < t1_nogap.DateTime and
t1_nogap.DateTime < t1b.DateTime
inner join
Table2 t2
on
t2.DateTime >= t1a.DateTime and
(t2.DateTime < t1b.DateTime or t1b.DateTime is null)
WHERE
t1_nogap.RecordID is null
(显然,其他查询可以类似地重写)
答案 1 :(得分:0)
SELECT T1.ID, T1.DateTime
FROM Table1 T1, Table2 T2
WHERE T2.DateTime BETWEEN T1.DateTime AND (SELECT MIN(T3.DateTime)
FROM Table1 T3 WHERE T3.ID > T1.ID)
UNION ALL
SELECT T2.ID, T2.DateTime
FROM Table2 T2
WHERE T2.ID > (SELECT MAX(T1.ID) FROM Table1)
答案 2 :(得分:0)
也许这就是你想要的。
declare @T1 table (RecordID int, [DateTime] datetime)
declare @T2 table (RecordID int, [DateTime] datetime)
insert into @T1 values
(1, '2010-01-01'),
(2, '2010-02-01'),
(3, '2010-03-01'),
(4, '2010-04-01')
insert into @T2 values
(10, '2010-02-10'),
(11, '2010-02-11'),
(12, '2010-04-15')
select distinct T1_3.RecordID
from @T2 as T2
inner join
(select
T1_1.RecordID as RecordID,
T1_1.[DateTime] as StartDate,
(select top 1 T1_2.[DateTime]
from @T1 as T1_2
where T1_1.[DateTime] < T1_2.[DateTime]) as EndDate
from @T1 as T1_1) as T1_3
on T2.[DateTime] >= T1_3.StartDate and
T2.[DateTime] < coalesce(T1_3.EndDate, '9999-12-31')