[英]Creating a date table for multiple primary keys between a specified open and close date for each primary key
Good day,再会,
I have been wracking my brain for the past few hours to build a table that looks like this:在过去的几个小时里,我一直在绞尽脑汁来构建一个看起来像这样的表:
I have about 33 000 entries that have their own opening and closing dates.我有大约 33 000 个条目,它们有自己的开始和结束日期。 I am trying to build a table that puts each of the dates (including the opening and closing dates) in a single row per entry (JOURNAL_NO) below each other in SQL Server Management Studio.
我正在尝试构建一个表,将每个日期(包括开始和结束日期)放在 SQL Server Management Studio 中每个条目 (JOURNAL_NO) 的单个行中。
I need to run a check on each day for each entry and I have tried to build the table by making use of my primary table and a calendar table that I created.我需要每天对每个条目进行一次检查,并且我尝试通过使用我的主表和我创建的日历表来构建该表。 Please refer to the code below (I have also included the calendar code below this):
请参考下面的代码(我还在下面添加了日历代码):
Code I'm trying to get working:我试图开始工作的代码:
DECLARE @START_DATE date = '2014-01-01',
@END_DATE date = '2018-12-31'
WHILE @START_DATE <= @END_DATE
BEGIN
SET @START_DATE = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY N) - 1, @START_DATE)
SELECT LO_MASTER.JOURAL_NO, --(33000 entries)
LO_MASTER.START_DATE, -- each entry has a different opening date
CAL.DATE -- date in calendar table
CAL.DAY AS DATEPART(DAY,[DATE]),
CAL.MONTH AS DATEPART(MONTH,[DATE]),
CAL.YEAR AS DATEPART(YEAR,[DATE]), -- these will be the date parts between the OPEN_DATE & CLOSE_DATE for each account
LO_MASTER.END_DATE -- each entry has a different closing date
FROM [dbo.][F1_master] as LO_MASTER
inner join CALENDAR_TABLE as CAL LO_MASTER.DATE = CAL.DATE
WHERE CAL.DATE between LO_MASTER.START_DATE and LO_MASTER.END_DATE -- range where the fields from table b need to be populated for each account
END
Table definition:表定义:
USE [master]
GO
/****** Object: Table [dbo].[dummy_data] Script Date: 11/02/2019 07:31:59 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[dummy_data](
[JOURNAL_NO] [int] NULL,
[START_DATE] [date] NULL,
[END_DATE] [date] NULL,
[DURATION_ON_BOOK] [int] NULL
) ON [PRIMARY]
GO
Sample data:样本数据:
JOURNAL_NO START_DATE END_DATE DURATION_ON_BOOK
101388 15/01/2014 01/01/2017 35
101499 14/01/2014 21/01/2017 36
101502 17/01/2014 17/02/2017 53
101876 06/01/2014 30/09/2017 35
101877 06/01/2014 24/01/2018 60
101878 07/01/2014 28/02/2018 60
101879 07/01/2014 19/01/2017 50
101881 07/01/2014 16/04/2018 58
101882 07/01/2014 13/11/2018 58
101883 08/01/2014 17/11/2016 59
101884 13/01/2014 26/06/2018 60
101886 13/01/2014 20/12/2016 59
101887 13/01/2014 13/12/2016 60
101888 13/01/2014 11/09/2017 43
101889 14/01/2014 07/12/2017 68
101890 14/01/2014 02/01/2018 58
101892 15/01/2014 21/02/2017 38
101893 17/01/2014 15/09/2017 64
101894 21/01/2014 02/02/2017 40
101896 21/01/2014 09/05/2016 38
101904 27/01/2014 21/12/2016 69
101906 27/01/2014 11/11/2016 36
101966 07/01/2014 10/03/2017 36
101967 07/01/2014 09/07/2018 40
102073 07/01/2014 15/09/2016 60
102074 13/01/2014 20/06/2017 40
102076 14/01/2014 15/06/2016 40
102077 15/01/2014 01/12/2016 60
102079 17/01/2014 12/10/2016 40
102081 21/01/2014 20/04/2017 40
102082 23/01/2014 14/02/2017 38
102234 02/01/2014 20/09/2017 46
102236 08/01/2014 05/05/2017 36
102237 15/01/2014 23/08/2017 68
102240 21/01/2014 27/02/2018 50
102241 21/01/2014 25/08/2016 37
102253 06/01/2014 26/10/2016 27
102254 07/01/2014 17/11/2016 61
102255 07/01/2014 26/04/2017 38
102256 10/01/2014 11/10/2017 42
102258 13/01/2014 18/05/2017 26
102263 17/01/2014 29/11/2018 74
102265 20/01/2014 31/10/2016 31
102372 06/01/2014 25/04/2017 35
102463 09/01/2014 25/08/2017 69
102464 09/01/2014 01/07/2016 26
102465 15/01/2014 24/12/2016 36
102530 06/01/2014 24/12/2017 48
102531 07/01/2014 28/08/2017 76
102532 09/01/2014 21/06/2017 39
Could anyone please assist me?有人可以帮助我吗? I haven't been coding that long and my troubleshoot attempts aren't providing any correct solutions.
我没有写那么长时间的代码,我的故障排除尝试没有提供任何正确的解决方案。 It would be greatly appreciated.
这将不胜感激。
Thank you.谢谢你。
Using a tally table this is pretty simple.使用计数表这非常简单。 I keep one on my system as a view that is lightning fast because it doesn't need any disc I/O at all.
我在我的系统上保留了一个视图,因为它根本不需要任何磁盘 I/O。 It look amazingly similar to what you had posted initially.
它看起来与您最初发布的内容惊人地相似。
create View [dbo].[cteTally] as
WITH
E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
select N from cteTally
GO
Next we need some sample data.接下来我们需要一些样本数据。 I stripped this down to just a couple of journals to demonstrate.
我将其精简为几本期刊以进行演示。
declare @dummy_data table
(
JOURNAL_NO int
, START_DATE datetime
, END_DATE datetime
, DURATION_ON_BOOK int
)
insert @dummy_data values
(101388, '20140115', '20170101', 35)
, (101499, '20160114', '20170121', 36)
Now we just need to leverage the power of a tally table with your data.现在我们只需要利用统计表的强大功能来处理您的数据。 This is what your query might look like.
这就是您的查询可能的样子。 No need for loops, just some basic date math.
不需要循环,只需要一些基本的日期数学。
select *
, EachDay = dateadd(day, t.N - 1, d.Start_Date)
, MyDay = t.N
, MyMonth = datediff(month, d.Start_DATE, dateadd(day, t.N - 1, d.Start_Date)) + 1
, MyYear = datepart(year, dateadd(day, t.N - 1, d.Start_Date))
from @dummy_data d
join cteTally t on t.N <= datediff(day, d.START_DATE, d.END_DATE) + 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.