Скользящий 3 года данных в нужном формате - PullRequest
0 голосов
/ 18 октября 2019

Дата начала = 2016-03-01 Дата окончания = 2019-02-15

Мне нужен запрос / функция, которая должна получить приведенный ниже результат на основе даты начала и окончания. У меня есть запрос для кадрирования результата. Но мне нужен какой-то запрос / функция для получения результирующего набора за 5-10 секунд с производительностью

enter image description here

Ответы [ 3 ]

0 голосов
/ 18 октября 2019

Мне пришло в голову, что вы, вероятно, ищете запрос, чтобы сгенерировать этот набор результатов из ничего. В sqlserver мы можем использовать рекурсивный cte:

DECLARE @dateFrom DATE = '2016-03-01'
DECLARE @dateTo DATE = '2019-02-15'

with d as (
        SELECT @datefrom as m
        UNION ALL
        SELECT DATEADD(MONTH,1,reqDate)
        FROM d
        WHERE DATEADD(MONTH,1,reqDate) <= @dateto
    ),
    SELECT 
        CONCAT( 
          DATENAME(MONTH, @dateFrom), ' ',
          CASE WHEN MONTH(d.m) < MONTH(@dateFrom) THEN YEAR(d.m) - 1 ELSE YEAR(d.m) END, '-',
          DATENAME(MONTH, @dateTo), ' ',
          CASE WHEN MONTH(d.m) < MONTH(@dateFrom) THEN YEAR(d.m) ELSE YEAR(d.m) +1 END
        ) as range,
        MONTH(d.m) as month,
        d.m as startdate,--do not use spaces in column names 
       CASE WHEN @dateTo < EOMONTH(d.m) then @dateTo ELSE EOMONTH(d.m) END as enddate --or dateadd 1 month then dateadd -1 day if you don't have eomonth
    FROM d
    OPTION(MAXRECURSION 0);
0 голосов
/ 18 октября 2019

Тот же формат, что и ваш результат, попробуйте.

DECLARE @StartDate DATETIME, @EndDate DATETIME
SET @StartDate = '2016-03-01'
SET @EndDate = '2038-02-15'

;WITH CTEs AS 
(
    SELECT @StartDate as [Start Date]
    UNION ALL
    SELECT DATEADD(MONTH,1,[Start Date])
    FROM CTEs WHERE DATEADD(MONTH,1,[Start Date]) <= @EndDate
)


SELECT 
     CONCAT( 
          DATENAME(MONTH, @StartDate), ' ',
          CASE WHEN MONTH([Start Date]) < MONTH(@StartDate) THEN YEAR([Start Date]) - 1 ELSE YEAR([Start Date]) END, '-',
          DATENAME(MONTH, @EndDate), ' ',
          CASE WHEN MONTH([Start Date]) < MONTH(@StartDate) THEN YEAR([Start Date]) ELSE YEAR([Start Date]) + 1 END
      ) AS [Range],
    MONTH([Start Date]) AS [Month],
    CONVERT(VARCHAR(10),[Start Date],101) AS [Start Date], 
    CONVERT(VARCHAR(10),(CASE WHEN [Start Date] <> DATEFROMPARTS(YEAR(@EndDate),MONTH(@EndDate),1) 
        THEN EOMONTH([Start Date]) 
        ELSE @EndDate 
    END),101) AS [End Date] 
FROM CTEs
OPTION(MAXRECURSION 0);
0 голосов
/ 18 октября 2019

Вы имеете в виду, как

SELECT * FROM table WHERE [start date]>='2016-03-01' AND [end date]<='2019-02-15'

Я что-то упустил? Это кажется слишком простым, чтобы задавать вопрос

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

CREATE INDEX IX_table_startdate_enddate  
ON schema.table ([start date], [end date])  
INCLUDE (othercolumn1, othercolumn2);  

Это означает, что на запросы типа:

SELECT othercolumn1, othercolumn2 FROM table 
WHERE [start date]>='2016-03-01' AND [end date]<='2019-02-15'

можно ответить из индекса, не подключая индекс к таблице, чтобы получить нужные данные

Если после этого вы все еще не можете сделать что-то неправильно, возможно, в вашем приложении есть недостаток дизайна;Плата за большие объемы данных за короткий промежуток времени может быть решена другим способом, например, только отправка событий, когда данные действительно изменяются

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...