SQL для выбора JOIN для года, месяца, дня между двумя датами - PullRequest
0 голосов
/ 17 мая 2018

Я работаю над объединением двух таблиц с YEAR, MONTH и DAY между двумя датами, разбитыми в результатах запроса. В таблице A могут быть некоторые даты, которых нет в таблице B, но мне нужно показывать результаты null / 0 независимо от того, есть дата для присоединения или нет.

Я ищу руководство по созданию отдельного запроса (или функции), который принимает даты начала и окончания, разбивает их на ГОД, МЕСЯЦ, ДЕНЬ, поэтому я могу использовать их в качестве своей базы для объединения с двумя другими таблицами .

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

declare @date datetime = '1/1/2018'
select  dateadd(hour, number, cast(floor(cast(@date as float)) as datetime)) as StartHour, 
        dateadd(hour, number+1, cast(floor(cast(@date as float)) as datetime)) as EndHour 
from master.dbo.spt_values 
where number < 24 and type = 'p

StartHour               EndHour
2018-01-01 00:00:00.000 2018-01-01 01:00:00.000
2018-01-01 01:00:00.000 2018-01-01 02:00:00.000
2018-01-01 02:00:00.000 2018-01-01 03:00:00.000
...
2018-01-01 22:00:00.000 2018-01-01 23:00:00.000
2018-01-01 23:00:00.000 2018-01-02 00:00:00.000

Заранее спасибо! Dan

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Вы можете создать таблицу подсчета для ваших дат на лету, как это:

DECLARE @start DATETIME='20000101';
DECLARE @end DATETIME='20180517';

WITH
    [days] AS (
                  SELECT TOP(DATEDIFF(d, @start, @end)+1)ROW_NUMBER() OVER (ORDER BY t1.object_id) AS N
                  FROM master.sys.all_columns t1
                       CROSS JOIN master.sys.all_columns t2
              ),
    tally(myDate) AS (SELECT DATEADD(d, [days].N-1, @start)FROM [days])
SELECT * FROM tally;
0 голосов
/ 17 мая 2018

Здесь я иду к таблице подсчета или чисел.Это идеально подходит для такого рода вещей.Я веду учетную таблицу в своей системе в таком виде.

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

Теперь у вас есть возможность мгновенно запросить до 10 000 последовательных чисел.Но как мы используем это для такого вопроса, как ваш?

declare @StartDate datetime = '20180501'
    , @EndDate datetime = '20180520'

select dateadd(day, t.N - 1, @StartDate)
from cteTally t
where t.N <= datediff(day, @StartDate, @EndDate) + 1
order by t.N

- РЕДАКТИРОВАТЬ - Не совсем понятно, хотите ли вы часы или дни.Но если вам нужны часы, просто измените функцию DATEDIFF на час вместо дня.

...