简体   繁体   English

为每个主键的指定打开和关闭日期之间的多个主键创建日期表

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM