[英]Selecting records from slowly changing table with a set of dates
I have a slowly changing table,a new row is created each time any of the source fields are changed.我有一个缓慢变化的表,每次更改任何源字段时都会创建一个新行。 Some metadata is added to show when that version was valid.
添加了一些元数据以显示该版本何时有效。 This is a simplified example(dates are dd/mm/yyyy format) that doesn't show the fields which have changed.
这是一个简化的示例(日期为 dd/mm/yyyy 格式),它不显示已更改的字段。
Startdate![]() |
Enddate![]() |
Currentrecord![]() |
unique id![]() |
serial_number![]() |
---|---|---|---|---|
15/12/2020 ![]() |
31/12/2020 ![]() |
0 ![]() |
1 ![]() |
2345 ![]() |
15/12/2020 ![]() |
8/3/2021 ![]() |
0 ![]() |
2 ![]() |
1234 ![]() |
19/9/2020 ![]() |
15/2/2021 ![]() |
0 ![]() |
3 ![]() |
2345 ![]() |
15/12/2020 ![]() |
8/3/2021 ![]() |
0 ![]() |
4 ![]() |
3456 ![]() |
9/3/2021 ![]() |
10/3/2021 ![]() |
0 ![]() |
5 ![]() |
3456 ![]() |
16/2/2021 ![]() |
10/3/2021 ![]() |
0 ![]() |
6 ![]() |
2345 ![]() |
9/3/2021 ![]() |
26/3/2021 ![]() |
0 ![]() |
7 ![]() |
1234 ![]() |
27/3/2021 ![]() |
2/5/2021 ![]() |
0 ![]() |
8 ![]() |
1234 ![]() |
11/3/2021 ![]() |
17/5/2021 ![]() |
0 ![]() |
9 ![]() |
3456 ![]() |
3/3/2021 ![]() |
27/4/2021 ![]() |
0 ![]() |
10 ![]() |
4567 ![]() |
20/1/2021 ![]() |
7/4/2021 ![]() |
0 ![]() |
11 ![]() |
5678 ![]() |
3/5/2021 ![]() |
30/6/2021 ![]() |
1 ![]() |
12 ![]() |
1234 ![]() |
25/5/2021 ![]() |
31/5/2021 ![]() |
0 ![]() |
13 ![]() |
2345 ![]() |
8/4/2021 ![]() |
22/5/2021 ![]() |
0 ![]() |
14 ![]() |
5678 ![]() |
1/6/2021 ![]() |
26/6/2021 ![]() |
0 ![]() |
15 ![]() |
2345 ![]() |
18/5/2021 ![]() |
3/6/2021 ![]() |
0 ![]() |
16 ![]() |
3456 ![]() |
27/6/2021 ![]() |
2/8/2021 ![]() |
0 ![]() |
17 ![]() |
2345 ![]() |
28/4/2021 ![]() |
28/6/2021 ![]() |
0 ![]() |
18 ![]() |
4567 ![]() |
23/5/2021 ![]() |
6/9/2021 ![]() |
0 ![]() |
19 ![]() |
5678 ![]() |
4/6/2021 ![]() |
28/6/2021 ![]() |
0 ![]() |
20 ![]() |
3456 ![]() |
29/6/2021 ![]() |
25/7/2021 ![]() |
0 ![]() |
21 ![]() |
3456 ![]() |
3/8/2021 ![]() |
31/12/9999 ![]() |
1 ![]() |
22 ![]() |
2345 ![]() |
26/7/2021 ![]() |
31/12/9999 ![]() |
1 ![]() |
23 ![]() |
3456 ![]() |
15/10/2021 ![]() |
31/12/9999 ![]() |
1 ![]() |
24 ![]() |
4567 ![]() |
7/9/2021 ![]() |
1/11/2021 ![]() |
0 ![]() |
25 ![]() |
5678 ![]() |
22/9/2021 ![]() |
10/11/2021 ![]() |
0 ![]() |
26 ![]() |
6789 ![]() |
2/11/2021 ![]() |
16/11/2021 ![]() |
0 ![]() |
27 ![]() |
5678 ![]() |
17/11/2021 ![]() |
21/11/2021 ![]() |
0 ![]() |
28 ![]() |
5678 ![]() |
15/7/2021 ![]() |
31/12/9999 ![]() |
1 ![]() |
29 ![]() |
7891 ![]() |
22/11/2021 ![]() |
31/12/9999 ![]() |
1 ![]() |
30 ![]() |
5678 ![]() |
26/11/2021 ![]() |
31/12/9999 ![]() |
1 ![]() |
31 ![]() |
6789 ![]() |
15/6/2021 ![]() |
31/12/9999 ![]() |
1 ![]() |
32 ![]() |
8912 ![]() |
There is only one record for each serial_number for any given point in time (ie the dates ranges will not overlap for identical serial_numbers) but there might be gaps between episodes for a some serial_numbers (representing something leaving and returning after a gap in service).对于任何给定的时间点,每个序列号只有一条记录(即,相同序列号的日期范围不会重叠),但某些序列号的剧集之间可能存在间隔(表示在服务间隔后离开和返回的东西)。
I want to supply an arbitrary list of datetimes, say midnight on 01/01/2021, 15/03/2021, 27/05/2021.我想提供任意日期时间列表,例如 2021 年 1 月 1 日、2021 年 3 月 15 日、2021 年 5 月 27 日午夜。 23/10/2021.
2021 年 10 月 23 日。 I want to return a set of records, containing every record which was in effect on each of the dates, with each row labelled with the date it was selected by.
我想返回一组记录,其中包含在每个日期有效的每条记录,每一行都标有它被选中的日期。 So the above example should return this.
所以上面的例子应该返回这个。
date![]() |
unique id![]() |
serial_number![]() |
---|---|---|
1/1/2021 ![]() |
2 ![]() |
1234 ![]() |
1/1/2021 ![]() |
3 ![]() |
2345 ![]() |
1/1/2021 ![]() |
4 ![]() |
3456 ![]() |
15/3/2021 ![]() |
7 ![]() |
1234 ![]() |
15/3/2021 ![]() |
9 ![]() |
3456 ![]() |
15/3/2021 ![]() |
10 ![]() |
4567 ![]() |
15/3/2021 ![]() |
11 ![]() |
5678 ![]() |
27/5/2021 ![]() |
12 ![]() |
1234 ![]() |
27/5/2021 ![]() |
13 ![]() |
2345 ![]() |
27/5/2021 ![]() |
16 ![]() |
3456 ![]() |
27/5/2021 ![]() |
18 ![]() |
4567 ![]() |
27/5/2021 ![]() |
19 ![]() |
5678 ![]() |
23/10/2021 ![]() |
22 ![]() |
2345 ![]() |
23/10/2021 ![]() |
23 ![]() |
3456 ![]() |
23/10/2021 ![]() |
24 ![]() |
4567 ![]() |
23/10/2021 ![]() |
25 ![]() |
5678 ![]() |
23/10/2021 ![]() |
26 ![]() |
6789 ![]() |
23/10/2021 ![]() |
29 ![]() |
7891 ![]() |
23/10/2021 ![]() |
32 ![]() |
8912 ![]() |
I can see how to do this with a cursor, stepping through each date putting them into a variable and using something like我可以看到如何使用 cursor 执行此操作,逐步将每个日期放入变量中并使用类似
select @date, [unique id], serial_number
from example
where @date between start_date and end_date
to get the rows.获取行。
I can't work out a pattern that would do it in a set based approach.我无法制定出一种以基于集合的方法进行的模式。 My preferred SQL version is TSQL.
我首选的 SQL 版本是 TSQL。 Sorry as this is almost certainly a repeat, but I can't find a form of words that hits a worked example.
抱歉,这几乎可以肯定是重复的,但我找不到能打出有效示例的单词形式。
You can use a temporary table to accomplish this.您可以使用临时表来完成此操作。
CREATE TABLE #RequestedDates([Date] DATE)
You insert your dates you want into a temporary table.您将所需的日期插入到临时表中。
INSERT INTO #RequestedDates([Date])
VALUES ('2021-01-01'), ('2021-03-15') /*Other dates*/
And then you join with the temporary table and use the between clause to get the valid results.然后加入临时表并使用 between 子句获得有效结果。
SELECT rd.[Date]
, t.UniqueId
, t.SerialNumber
FROM MyTable t
INNER JOIN #RequestedDates rd on rd.[Date] BETWEEN t.StartDate AND t.EndDate
ORDER BY rd.[Date]
, t.UniqueId
, t.SerialNumber
You can join to VALUES
with the dates you need.您可以在需要的日期加入
VALUES
。
Then join the datetimes on the range.然后加入范围内的日期时间。
SELECT
datetimes.dt as [date]
, t.[unique id]
, t.serial_number
FROM example t
JOIN (VALUES
(cast('2021-01-01 00:00:00' as datetime)),
('2021-03-15 00:00:00'),
('2021-05-27 00:00:00'),
('2021-10-23 00:00:00')
) datetimes(dt)
ON datetimes.dt >= t.start_date
AND datetimes.dt <= t.end_date
ORDER BY datetimes.dt, t.[unique id], t.serial_number
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.