2008-09-18 4 views
10

Я просто хочу, чтобы быстрый способ (и предпочтительно не использовать цикл while) создания таблицы каждой даты между датой @x и датой @y так я может оставить внешнее соединение в некоторых таблицах статистики, некоторые из которых не будут иметь записей в течение определенных дней между ними, что позволит мне отмечать недостающие дни с помощью 0Как получить таблицу дат между x и y в sql server 2005

ответ

18

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

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

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) 
+0

Ты гений! Молодец, не думал об использовании CTE! – digiguru 2008-09-18 19:26:09

-4

Just: WHERE col> дата начала и номер < дата окончания

+0

Он пытается создать таблицу, чтобы сделать левое внешнее соединение. Это не будет делать то, что он хочет сделать. – 2008-09-18 18:25:08

3

Я считаю, что вы ищете this blog post.

+0

Это грязно, но он выполняет работу – digiguru 2008-09-18 18:26:47

+0

И он переносится на другие SQL-устройства (включая Server 2000). :) – IDisposable 2009-10-19 19:54:24

0

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

0

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

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

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

0

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

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 

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

-1

Просто напишите петлю. Кто-то должен написать цикл для этого, будь то вы - или 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 
1

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

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

Небольшое завихрение при ответе на вопрос 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)