Создание таблицы дат для нескольких первичных ключей между указанной датой открытия и закрытия для каждого первичного ключа - PullRequest
0 голосов
/ 11 февраля 2019

Добрый день,

Последние несколько часов я ломал голову над созданием таблицы, которая выглядит следующим образом:

enter image description here

У меня около 33 000 записей, которые имеют свои даты открытия и закрытия.Я пытаюсь создать таблицу, в которой каждая из дат (включая даты открытия и закрытия) помещается в одну строку для каждой записи (JOURNAL_NO) ниже друг друга в SQL Server Management Studio.

Мне нужно проверять каждый день для каждой записи, и я попытался построить таблицу, используя основную таблицу и созданную мной таблицу календаря.Пожалуйста, обратитесь к приведенному ниже коду (я также включил код календаря ниже):

Код, который я пытаюсь получить:

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

Определение таблицы:

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

Пример данных:

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

Может ли кто-нибудь помочь мне?Я так долго не кодировал, и мои попытки устранения неполадок не дают правильных решений.Был бы очень признателен.

Спасибо.

1 Ответ

0 голосов
/ 11 февраля 2019

Используя таблицу подсчета, это довольно просто.Я держу один в моей системе как молниеносное представление, потому что оно вообще не требует дискового ввода-вывода.Это выглядит удивительно похоже на то, что вы опубликовали вначале.

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

Далее нам понадобятся примеры данных.Я сократил это до пары журналов для демонстрации.

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)

Теперь нам просто нужно использовать мощь таблицы подсчета с вашими данными.Вот как может выглядеть ваш запрос.Нет необходимости в циклах, просто некоторая базовая математика для дат.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...