2014-11-14 2 views
2

Я надеюсь, что название более или менее в порядке, не знал, как описать мою проблему.Создать «виртуальные» данные по запросу?

Что я хотел бы сделать, так это создать временные ряды дат, которые находятся между датами, которые пользователь может выбрать, без фактического сохранения дат в таблице. Скажем, это 15 ноября 2014 и 16 ноября 2014 Я хотел бы иметь запрос, который дает мне:

[date] 
11-15-2014 00:00 
11-15-2014 01:00 
11-15-2014 02:00 
.. 
11-15-2014 23:00 

Есть ли способ, чтобы создать эти даты с запросом (и, возможно, таблица, содержащая дату начала) только?

Я thougt о чем-то вроде

SELECT Dateadd('h', i, t1.start_date) as date FROM t1 

, а затем какая-то часть слова «я» будет находиться в диапазоне от 0 до DateDiff («ч», start_date дата_окончания)

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

Прямо сейчас я использую обходной путь, где у меня есть таблица, содержащая значение даты каждого часа в течение нескольких лет, и где я использую ЛЕВЫЙ ПРИСОЕДИНЕНИЕ ... ГДЕ МЕЖДУ МЕЖДУ, но мне это не нравится «грязный» трюк.

Заранее благодарен!

+1

Ваш «грязный» трюк является действительно правильным и хорошим решением. В течение нескольких часов вы можете использовать не одну, а две дополнительные таблицы - по одной записи за каждый день в первой и 24 записи (за каждый час) в другой таблице. – Arvo

+0

Хорошо, я вижу :) Спасибо. – frrrt

ответ

0

Существует способ сделать это, но это также немного «грязный»:

select d.BaseDay, h.Hour, DateAdd(HH, h.Hour, d.BaseDay) 
from 
(
    select convert(datetime, '15 Nov 2014') BaseDay 
    union select dateadd(D, 1, convert(datetime, '15 Nov 2014')) 
    union select dateadd(D, 2, convert(datetime, '15 Nov 2014')) 
    union select dateadd(D, 3, convert(datetime, '15 Nov 2014')) 
    union select dateadd(D, 4, convert(datetime, '15 Nov 2014')) 
    union select dateadd(D, 5, convert(datetime, '15 Nov 2014')) 
    union select dateadd(D, 6, convert(datetime, '15 Nov 2014')) 
    union select dateadd(D, 7, convert(datetime, '15 Nov 2014')) 
    union select dateadd(D, 8, convert(datetime, '15 Nov 2014')) 
    union select dateadd(D, 9, convert(datetime, '15 Nov 2014')) 
    union select dateadd(D, 10, convert(datetime, '15 Nov 2014')) 
    union select dateadd(D, 11, convert(datetime, '15 Nov 2014')) 
    -- continue for as many days as you want 
    -- to cover the max period you'll want 
) d 
cross join 
(
    select 0 Hour 
    union select 1 
    union select 2 
    union select 3 
    union select 4 
    union select 5 
    union select 6 
    -- continuing up to hour 23 excluded for brevity 
) h 
where d.BaseDay < '16 Nov 2014' 

Два жестко закодированные сроки будут параметры (@startDate и @endDate) в надлежащей реализации.

Два недостатка: Количество дней между датой начала и окончания ограничено только тем, что вы можете стоять на клавиатуре (в этом случае 11), а дни смены часов вообще не обслуживаются.

Одно из преимуществ. Хотя это потребует некоторых ресурсов от SQL Server для запуска, он вообще не будет генерировать доступ к диску, и поэтому будет довольно быстрым и не повлияет на другие запросы, требующие доступа к диску.

Я не обязательно рекомендую это. Я просто замечаю, что это возможно.

+2

Синтаксис не будет работать в MS Access (отметить теги OP), хотя общая идея реализуема. Что ж, для больших временных интервалов (более чем лет или около того) я думаю, что механизм запросов MS Access не будет работать с таким объединением. – Arvo

+0

Я не заметил тег Access. И более двух дней или недель я бы не рекомендовал этот метод. –

Смежные вопросы