2014-07-09 3 views
2

Si j'ai une colonne DATETIMEOFFSET dans une table SQL Server, quel est le bon moyen de filtrer les résultats à une plage de dates locales (pas UTC)? Par "local", je veux dire que les limites de date sont relatives au fuseau horaire de chaque valeur stockée (qui peut différer entre les lignes), et non pas à un seul fuseau horaire local fixe. Je suppose que ce n'est pas cela, parce que les littéraux DATE seront supposés être UTC. Correct?Filtrage d'une colonne DATETIMEOFFSET dans une plage de dates locale

WHERE EventTime >= '20140401' AND EventTime < '20140501' 

Alors, est-ce la bonne solution?

WHERE CAST (EventTime AS DATE) >= '20140401' AND CAST (EventTime AS DATE) < '20140501' 

Ou la fonction de prévention CAST utilisation efficace des indices sur la colonne EventTime? Si oui, quelle est la bonne façon d '"aligner" les littéraux de date sur le même fuseau horaire que la colonne DATETIMEOFFSET?

Répondre

3

Oui, vous pouvez convertir la colonne EventTime en un type date, qui supprimera toutes les informations de décalage et de date, vous laissant la date locale. Mais comme vous l'avez souligné, il y aura un coût de performance si vous lancez la colonne au moment de la requête.

Vous devez envisager de créer une colonne distincte de type date à cette fin. Vous pouvez le faire dans une vue, ou vous pouvez simplement créer une colonne calculée. Vous pouvez ensuite créer un index sur cette colonne. Par exemple:

CREATE TABLE Events (
    EventID int NOT NULL, 
    EventTime datetimeoffset NOT NULL, 
    LocalDate AS (CONVERT(date, EventTime)), -- this is the computed column 
    CONSTRAINT PK_Events PRIMARY KEY CLUSTERED (EventID) 
) 
CREATE NONCLUSTERED INDEX IX_Events_LocalDate ON Events (
    LocalDate 
) 

Vous pouvez ensuite interroger par le champ LocalDate et il aura les informations dont vous avez besoin et l'indice approprié.