Добавить недостающие записи в записи таблицы результатов - PullRequest
2 голосов
/ 30 января 2020

У меня следующая проблема: у меня две таблицы

Article
id     state
Guid    int

и

Article_history
id   state   datechange
Guid  int     datetime

В первой таблице хранится информация о товаре, во второй заполняется, а затем изменяется состояние продукта. Например,

Article
id     state
1       1

Article_history
id   state   datechange
1     1      2019-11-10
1     2      2020-01-15

Мне нужно создать отчет для каждой статьи за несколько лет с шагом в один месяц:

date         id   state
2019-11-01   1    1
2019-12-01   1    1 --There is my problem
2020-01-01   1    2

Я создаю запрос к таблице Article_history, но так как мой приложение создает запись только при изменении Article state не каждый месяц представлен в Article_history. В моем примере у меня фактически нет записи на 2019-12-01. Мне нужно заполнить промежутки времени для каждого продукта последним известным состоянием.

Я не могу придумать, как заполнить эти промежутки без использования курсора для каждого месяца в данном периоде, но это занимает много времени. Пожалуйста, дайте мне совет.

Макет

 Create TABLE Article
(
    id int,
    state int
)

Create TABLE Article_history
(
    id int,
    datechange datetime,
    state int
)

Insert into Article (id, state)
VALUES (1,1)
,(2,1)
,(3,2)

INSERT into Article_history (id, datechange, state)
VALUES (1,'2019-11-10',1)
,(1,'2020-01-15',2);

Мой запрос:

 With theDates As
(
    Select DATEFROMPARTS(2019,11,1) as theDate
    Union All
    Select DateAdd(MONTH,1,theDate)
    From theDates
    Where DATEADD(MONTH,1,theDate)<=GETDATE()
)
Select 
    Convert(date,dt.theDate,104) as 'date'
    ,arth.id
    ,arth.state
From theDates as dt
left join Article_history as arth
on arth.datechange>=DATEADD(month, DATEDIFF(month, 0, dt.theDate), 0) and arth.datechange<=EOMONTH(dt.theDate)
Option (Maxrecursion 0)

Мой результат:

date         id   state
2019-11-01   1    1
2020-01-01   1    2

Я хочу получить

 date         id   state
 2019-11-01   1    1
 2019-12-01   1    1 
 2020-01-01   1    2

Декабрь отсутствует

Чтобы прояснить мою проблему: запись с Article может вообще не быть в Article_history, если так, я хочу ставить эту запись каждый месяц с некоторые значения по умолчанию.

UPD: Article таблица содержит около 3 тыс. записей. PR ID в Article является FK для Article_history. Мне нужно создать представление для каждой записи в Article. В псевдокоде:

foreach article in Article {
  foreach month in TheDates {
    if(article.id not in result where result.month = month) {
      AddInResult(new [result.month=month, result.id=article.id, result.state = GetLastStateFromArticleHistory(article.id,month)]
    }
 }}

У меня есть таблица результатов с историей, но не все Article представлены для каждого месяца. Мне нужно добавить эти записи с последним доступным статусом для которого от Article_history.

1 Ответ

3 голосов
/ 30 января 2020

Во-первых, хорошая работа по предоставлению минимального примера и созданию сценариев. Кроме того, хорошо поработали над созданием необходимой таблицы подсчета - во многих отношениях cte просто отлично.

Теперь ваш результат не соответствует моему. Я получаю третий столбец с идентификатором и состоянием NULLS за декабрь. Может быть, вы действительно запустили внутреннее соединение?

With theDates As
(
    Select DATEFROMPARTS(2019,11,1) as theDate
    Union All
    Select DateAdd(MONTH,1,theDate)
    From theDates
    Where DATEADD(MONTH,1,theDate)<=GETDATE()
)
Select 
    Convert(date,dt.theDate,104) as 'date'
    ,a.id
    ,lastone.*
From theDates as dt
cross join Article a -- cartesian product of dates * articles
outer apply
(
    select top 1 state
    from Article_history as arth
    where 
        arth.datechange<EOMONTH(dt.theDate)
        and a.id=arth.id
    order by arth.datechange desc
) as lastone
order by id,dt.theDate

Result:

+------------+----+-------+
|    date    | id | state |
+------------+----+-------+
| 2019-11-01 |  1 | 1     |
| 2019-12-01 |  1 | 1     |
| 2020-01-01 |  1 | 2     |
| 2019-11-01 |  2 | NULL  |
| 2019-12-01 |  2 | NULL  |
| 2020-01-01 |  2 | NULL  |
| 2019-11-01 |  3 | NULL  |
| 2019-12-01 |  3 | NULL  |
| 2020-01-01 |  3 | NULL  |
+------------+----+-------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...