Вопрос

Я просто хочу быстрый способ (и желательно без использования цикла while) создания таблицы каждой даты между date @ x и date @ y, чтобы я мог left outer присоединиться к некоторым таблицам статистики, в некоторых из которых не будет записей за определенные дни между ними, что позволит мне отмечать пропущенные дни символом 0

Это было полезно?

Решение

Строго говоря, это не совсем ответ на ваш вопрос, но это довольно аккуратно.

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

WITH numbers ( n ) AS (
        SELECT 1 UNION ALL
        SELECT 1 + n FROM numbers WHERE n < 500 )
    SELECT DATEADD(day,n-1,'2008/11/01') FROM numbers
    OPTION ( MAXRECURSION 500 )

Другие советы

Я верю, что вы ищете это сообщение в блоге.

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

select  ...
from    Calendar
        left outer join
        ...
where   Calendar.Date >= @x
and     Calendar.Date <= @y

Я думаю, что вы могли бы с таким же успехом просто сделать это в цикле while.Я знаю, это некрасиво, но это просто и это работает.

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

Лучшее, что у меня получилось, - это временная таблица, а затем выбор дат, к которым я хотел присоединиться.

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

Я нашел другую таблицу, в которой хранится каждая дата (это посетители веб-сайта), так что как насчет этого?..

Declare @FromDate datetime,  
        @ToDate datetime  
Declare @tmpDates table   
            (StatsDate datetime)
Set @FromDate = DateAdd(day,-30,GetDate())
Set @ToDate = GetDate()

Insert Into  @tmpDates (StatsDate)
Select 
    distinct CAST(FLOOR(CAST(visitDate AS DECIMAL(12, 5))) AS DATETIME)
FROM tbl_visitorstats 
Where visitDate between @FromDate And @ToDate 
Order By CAST(FLOOR(CAST(visitDate AS DECIMAL(12, 5))) AS DATETIME) 


Select * FROM @tmpDates

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

Небольшой поворот в ответе, данном в виде https://stackoverflow.com/a/95728/395440.Позволяет указать дни, а также вычисляет диапазон до текущей даты.

DECLARE @startDate datetime
SET @startDate = '2015/5/29';

WITH number ( n ) AS (
        SELECT 1 UNION ALL
        SELECT 1 + n FROM dates WHERE n < DATEDIFF(Day, @startDate, GETDATE()) )
    SELECT DATEADD(day,n-1,@startDate) FROM number where
    datename(dw, DATEADD(day,n-1,@startDate)) in ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday')
    OPTION ( MAXRECURSION 500 )

Просто напишите цикл.Кто-то должен написать цикл для этого, будь то вы - или SQL Server.

DECLARE @Dates TABLE
(
  TheDate datetime PRIMARY KEY
)
DECLARE @StartDate datetime, @EndDate datetime
SELECT @StartDate = '2000-01-01', @EndDate = '2010-01-01'


DECLARE @LoopVar int, @LoopEnd int    
SELECT @LoopEnd = DateDiff(dd, @StartDate, @EndDate), @LoopVar = 0


WHILE @LoopVar <= @LoopEnd
BEGIN
  INSERT INTO @Dates (TheDate)
  SELECT DateAdd(dd,@LoopVar,@StartDate)

  SET @LoopVar = @LoopVar + 1
END


SELECT *
FROM @Dates

Просто:ГДЕ col > начальная дата И col < дата окончания

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top