Получить значения даты предыдущего месяца из данных, хранящихся в таблице SQL Server - PullRequest
0 голосов
/ 08 февраля 2019

Моя структура таблицы в SQL Server выглядит следующим образом.

id     startdate     enddate     value
---------------------------------------
1     2019-02-06    2019-02-07    11
1     2019-01-22    2019-02-05    10
1     2019-01-15    2019-01-21    14
1     2018-12-13    2018-01-14    15
1     2018-12-09    2018-12-12    14
1     2018-08-13    2018-12-08    17
1     2018-07-19    2018-08-12    19
1     2018-06-13    2018-07-18    20

Теперь мой запрос должен отображать значение с самой высокой даты начала этого месяца.Это нормально, и я знаю, что нужно сделать, но не начинать только самое высокое значение даты за этот месяц, если нет значения для этой даты начала, мы переносим значение с прошлого месяца.Таким образом, в основном, если вы обратите внимание на приведенные выше данные, после значений за декабрь 2018 года значения для ноября, октября, сентября и т. Д. Отсутствуют, но я хочу вернуть значения MM / YYYY для этого месяца в результате, но значения для этих месяцев должны быть такими, как мы нашли напредыдущий месяц, который представляет собой значения августа, которые в этом примере равны 17. Обратите внимание, что конечной датой всегда будет один день до начала новой даты начала.Вероятно, это можно использовать для обратного заполнения и переноса значений пропущенных месяцев?

Так что мой результат должен выглядеть следующим образом.

id     date         value
----------------------------
1     2019-02        11
1     2019-01        10
1     2018-12        15
1     2018-11        17
1     2018-10        17
1     2018-09        17
1     2018-08        17
1     2018-07        19
1     2018-06        20

Как вы думаете, это можно сделать без использования курсора здесь?

Ответы [ 2 ]

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

Ответ Александра Влока солидный, поэтому я не буду вдаваться в слишком много дополнительного кода.Но я думал, что объясню причину.По сути, вам нужно создать скелетную таблицу дат, содержащую все даты и первичные ключи, которые вы хотите вернуть.Я предполагаю, что у вас есть более чем одно значение id в ваших реальных данных, так что, вероятно, что-то вроде этого (хотите ли вы сохранить его или нет, зависит от вас)

create table #skelly
(
    id int,
    _year int,
    _month int

    primary key (id, _year, _month)
)

Вы можете получить многоточнее, если вам нужно, включив только даты, которые находятся между минимальной и максимальной StartDate на id, но это упражнение, которое я оставляю вам.

Оттуда это простовопрос заполнения значений, которые вам небезразличны, по отношению к этой скелетной таблице.Вы можете сделать это несколькими способами;путем объединения, перекрестного применения или коррелированного подзапроса (как использовал Александр Волок).

0 голосов
/ 08 февраля 2019
DECLARE @start DATE, @end DATE;
SELECT @start = '20180601', @end = GETDATE();

;WITH Months AS 
(

  SELECT EOMONTH(DATEADD(month, n-1, @start)) AS DateValue FROM (
  SELECT TOP (DATEDIFF(MONTH, @start, @end) + 1)   
  n = ROW_NUMBER() OVER (ORDER BY [object_id])
  FROM sys.all_objects
  ) D
)


, InputData AS 
(

SELECT 1  AS id,    '2019-02-06' startdate,    '2019-02-07' as enddate,   11 AS [value] UNION ALL
SELECT 1,     '2019-01-22',    '2019-01-25',    10 UNION ALL
SELECT 1,     '2019-01-15',    '2019-01-17',    14 UNION ALL
SELECT 1,     '2018-12-13',    '2018-12-19',    15 UNION ALL
SELECT 1,     '2018-12-09',    '2018-12-10',    14 UNION ALL
SELECT 1,     '2018-08-13',    '2018-12-08',    17 UNION ALL
SELECT 1,     '2018-07-19',    '2018-07-25',    19 UNION ALL
SELECT 1,     '2018-06-13',    '2018-07-18',    20 
)

SELECT  FORMAT(m.DateValue, 'yyyy-MM') AS [Month]
, (SELECT TOP 1 I.value FROM InputData I WHERE I.startdate < M.DateValue ORDER BY I.startdate DESC ) [Value]
FROM months m
ORDER BY M.DateValue DESC

Результаты до:

Month   Value
2019-02 11
2019-01 10
2018-12 15
2018-11 17
2018-10 17
2018-09 17
2018-08 17
2018-07 19
2018-06 20
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...