Службы отчетов SQL Server и время UTC - PullRequest
1 голос
/ 16 декабря 2009

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

В частности, давайте возьмем этот пример набора данных:

EmailAddress                DateCreated
random_email@example.com    2009-09-01 00:00:00
random_email@example.com    2009-09-01 00:00:00
random_email@example.com    2009-02-28 04:00:00
random_email@example.com    2009-04-27 14:33:00
random_email@example.com    2009-08-31 17:28:00
random_email@example.com    2009-03-19 18:57:00
random_email@example.com    2009-03-01 00:49:00
random_email@example.com    2009-02-28 04:00:00
random_email@example.com    2009-09-01 00:00:00
random_email@example.com    2009-09-16 00:00:00

Теперь предположим, что клиент хочет увидеть, сколько записей существует за февраль месяц, используя центральное стандартное время. Я не могу просто запросить записи, используя время UTC, потому что метка времени UTC должна быть преобразована в CST, прежде чем произойдет группировка. Другими словами, запись № 7 (2009-03-01 00:49:00) должна учитываться в феврале с использованием дат CST, даже если дата UTC прямо указывает на март месяц.

Что обычно заканчивается тем, что я пишу функцию для преобразования даты так, что запрос выглядит так:

select 
    dbo.ConvertToLocalDate(DateCreated), 
    count(*) as [Count]
from 
    example_table
group by 
    dbo.ConvertToLocalDate(DateCreated)

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

select 
    t3.LocalDateCreated, 
    count(*) as [Count]
from 
    example_table t1 
        inner join (
            select 
                t2.Email, 
                dbo.ConvertToLocalDate(t2.DateCreated) as LocalDateCreated
            from
                example_table t2) t3 on t3.Email = t1.Email
group by 
    t3.LocalDateCreated

Это все кажется мне по-настоящему хакерским. Есть ли лучший способ?

1 Ответ

1 голос
/ 16 декабря 2009

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

Таким образом, значение будет вычислено, когда оно будет вставлено, но вам не нужно нигде вычислять самостоятельно.

Кроме того, прочитайте мое сообщение о скалярных функциях в блоге по адресу http://msmvps.com/blogs/robfarley/archive/2009/12/05/dangers-of-begin-and-end.aspx - вы можете переосмыслить то, как вы используете эту функцию.

...