web-dev-qa-db-ja.com

SQL Server-日付フィールドをUTCに変換

システムを更新して、以前は現地時間として保存していた日付/時刻をUTCとして記録するようにしました。

ローカルに保存されているすべての日付/時刻をUTCに変換する必要があります。 .NETのConvertTimeメソッドに似た組み込み関数があるかどうか疑問に思っていましたか?

私はこれを行うためにユーティリティアプリを記述する必要を回避しようとしています。

助言がありますか?

48
James

それらがすべてローカルである場合、オフセットは次のとおりです。

SELECT GETDATE() AS CurrentTime, GETUTCDATE() AS UTCTime

以下を使用してすべてのデータを更新できるはずです。

UPDATE SomeTable
   SET DateTimeStamp = DATEADD(hh, DATEDIFF(hh, GETDATE(), GETUTCDATE()), DateTimeStamp)

それはうまくいくでしょうか、またはこの問題の別の角度がありませんか?

12
SqlRyan

上記のコードが機能するとは思わない。理由は、ローカル時間とUTC時間の現在の日付の差に依存するためです。たとえば、ここカリフォルニアでは現在PDT(太平洋夏時間)になっています。この時間とUTCの差は7時間です。提供されたコードは、今すぐ実行すると、変換が必要なすべての日付に7時間を追加します。ただし、保存された履歴日付または将来の日付が変換され、その日付が夏時間ではない場合、正しいオフセットが8の場合、7が追加されます。現在の日付のみを表示することにより、タイムゾーン間(UTCを含み、夏時間を遵守しません)。変換する日付自体を、その日に夏時間が有効であったかどうかを考慮する必要があります。さらに、夏時間と標準時間が変更される日付は変更されました(ジョージブッシュはアメリカの管理中に日付を変更しました!)。つまり、getdate()またはgetutcdate()を参照するソリューションも機能しません。変換する実際の日付を解析する必要があります。

74

SQL Server 2016では、 AT TIME ZONE ステートメント。これらを連鎖させて変換を行うことができます。

SELECT YourOriginalDateTime AT TIME ZONE 'Pacific Standard Time' AT TIME ZONE 'UTC'

または、これも同様に機能します:

SELECT SWITCHOFFSET(YourOriginalDateTime AT TIME ZONE 'Pacific Standard Time', '+00:00')

これらのいずれかが入力を太平洋時間で解釈し、DSTが有効であるかどうかを適切に考慮してから、UTCに変換します。結果は、オフセットがゼロのdatetimeoffsetになります。

CTPアナウンスメントのその他の例

38

前述したように、SQL Serverでタイムゾーンルールを意識した日付変換を実行するための組み込みの方法はありません(少なくともSQL Server 2012以降)。

これを行うには、基本的に3つの選択肢があります。

  1. SQL Serverの外部で変換を実行し、結果をデータベースに保存します
  2. スタンドアロンテーブルにタイムゾーンオフセットルールを導入し、ルールテーブルを参照して変換を実行するストアドプロシージャまたはUDFを作成します。このアプローチの1つを見つけることができます SQL Server Centralで (登録が必要です)
  3. SQL CLR UDFを作成できます。ここでアプローチを説明します

SQL Serverにはタイムゾーンルール対応の日付変換を実行するツールはありませんが、.NETフレームワークにはあります。SQLCLRを使用できる限り、それを利用できます。

Visual Studio 2012では、データツールがインストールされていることを確認し(インストールされていない場合、SQL Serverプロジェクトはオプションとして表示されません)、新しいSQL Serverプロジェクトを作成します。

次に、新しいSQL CLR C#ユーザー定義関数を追加し、「ConvertToUtc」と呼びます。 VSは、次のようなボイラープレートを生成します。

public partial class UserDefinedFunctions
{
    [Microsoft.SqlServer.Server.SqlFunction]
    public static SqlString ConvertToUtc()
    {
        // Put your code here
        return new SqlString (string.Empty);
    }
}

ここでいくつかの変更を行います。たとえば、SqlDateTimeではなくSqlStringを返します。第二に、私たちは何か役に立つことをしたいです。 :)

修正したコードは次のようになります。

public partial class UserDefinedFunctions
{
    [Microsoft.SqlServer.Server.SqlFunction]
    public static SqlDateTime ConvertToUtc(SqlDateTime sqlLocalDate)
    {
        // convert to UTC and use explicit conversion
        // to return a SqlDateTime
        return TimeZone.CurrentTimeZone.ToUniversalTime(sqlLocalDate.Value);
    }
}

この時点で、試してみる準備が整いました。最も簡単な方法は、Visual Studioの組み込みの発行機能を使用することです。データベースプロジェクトを右クリックし、[発行]を選択します。データベース接続と名前を設定し、「パブリッシュ」をクリックしてコードをデータベースにプッシュするか、スクリプトを後世に保存する(またはビットをプロダクションにプッシュする)場合は「スクリプトを生成」をクリックします。

データベースにUDFを作成すると、その動作を確認できます。

declare @dt as datetime
set @dt = '12/1/2013 1:00 pm'
select dbo.ConvertToUtc(@dt)
16
Michael Teper

データベースをローカル時間からUTC時間にアップグレードしたテスト済みの手順を次に示します。データベースのアップグレードに必要な入力は、ローカル時間をutc時間から@Offsetにオフセットする分数を入力することと、タイムゾーンが@ApplyDaylightSavingsを設定して夏時間調整の対象となる場合のみです。

たとえば、米国中部時間は6時間@ Offset = -360および@ ApplyDaylightSavings = 1と入力し、yesは夏時間調整を適用します。

データベース機能のサポート


CREATE FUNCTION [dbo].[GetUtcDateTime](@LocalDateTime DATETIME, @Offset smallint, @ApplyDaylightSavings bit) 
RETURNS DATETIME AS BEGIN 

    --====================================================
    --Calculate the Offset Datetime
    --====================================================
    DECLARE @UtcDateTime AS DATETIME
    SET @UtcDateTime = DATEADD(MINUTE, @Offset * -1, @LocalDateTime)

    IF @ApplyDaylightSavings = 0 RETURN @UtcDateTime;

    --====================================================
    --Calculate the DST Offset for the UDT Datetime
    --====================================================
    DECLARE @Year as SMALLINT
    DECLARE @DSTStartDate AS DATETIME
    DECLARE @DSTEndDate AS DATETIME

    --Get Year
    SET @Year = YEAR(@LocalDateTime)

    --Get First Possible DST StartDay
    IF (@Year > 2006) SET @DSTStartDate = CAST(@Year AS CHAR(4)) + '-03-08 02:00:00'
    ELSE              SET @DSTStartDate = CAST(@Year AS CHAR(4)) + '-04-01 02:00:00'
    --Get DST StartDate 
    WHILE (DATENAME(dw, @DSTStartDate) <> 'sunday') SET @DSTStartDate = DATEADD(day, 1,@DSTStartDate)


    --Get First Possible DST EndDate
    IF (@Year > 2006) SET @DSTEndDate = CAST(@Year AS CHAR(4)) + '-11-01 02:00:00'
    ELSE              SET @DSTEndDate = CAST(@Year AS CHAR(4)) + '-10-25 02:00:00'

    --Get DST EndDate 
    WHILE (DATENAME(dw, @DSTEndDate) <> 'sunday') SET @DSTEndDate = DATEADD(day,1,@DSTEndDate)

    --Finally add the DST Offset if needed 
    RETURN CASE WHEN @LocalDateTime BETWEEN @DSTStartDate AND @DSTEndDate THEN 
        DATEADD(MINUTE, -60, @UtcDateTime) 
    ELSE 
        @UtcDateTime
    END

END
GO

アップグレードスクリプト


  1. このスクリプトを実行する前にバックアップを作成してください!
  2. @Offsetおよび@ApplyDaylightSavingsを設定します
  3. 一度だけ実行してください!

begin try
    begin transaction;

    declare @sql nvarchar(max), @Offset smallint, @ApplyDaylightSavings bit;

    set @Offset = -360;             --US Central Time, -300 for US Eastern Time, -480 for US West Coast
    set @ApplyDaylightSavings = 1;  --1 for most US time zones except Arizona which doesn't observer daylight savings, 0 for most time zones outside the US

    declare rs cursor for
    select 'update [' + a.TABLE_SCHEMA + '].[' + a.TABLE_NAME + '] set [' + a.COLUMN_NAME + '] = dbo.GetUtcDateTime([' + a.COLUMN_NAME + '], ' + cast(@Offset as nvarchar) + ', ' + cast(@ApplyDaylightSavings as nvarchar) + ') ;'
    from INFORMATION_SCHEMA.COLUMNS a
        inner join INFORMATION_SCHEMA.TABLES b on a.TABLE_SCHEMA = b.TABLE_SCHEMA and a.TABLE_NAME = b.TABLE_NAME
    where a.DATA_TYPE = 'datetime' and b.TABLE_TYPE = 'BASE TABLE' ;

    open rs;
    fetch next from rs into @sql;
    while @@FETCH_STATUS = 0 begin
        exec sp_executesql @sql;
        print @sql;
        fetch next from rs into @sql;
    end
    close rs;
    deallocate rs;

    commit transaction;
end try
begin catch
    close rs;
    deallocate rs;

    declare @ErrorMessage nvarchar(max), @ErrorSeverity int, @ErrorState int;
    select @ErrorMessage = ERROR_MESSAGE() + ' Line ' + cast(ERROR_LINE() as nvarchar(5)), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE();
    rollback transaction;
    raiserror (@ErrorMessage, @ErrorSeverity, @ErrorState);
end catch
7
Ben Gripka

今日以外の日付を別のタイムゾーンに変換する必要がある場合は、夏時間に対処する必要があります。データベースのバージョンを気にせずに、ストアド関数やOracleに簡単に移植できるものを使用せずに実行できるソリューションが必要でした。

ウォーレンは夏時間の正しい日付を取得することで正しい軌道に乗っていると思いますが、複数のタイムゾーンと国の異なるルール、さらには2006年から2007年に米国で変更されたルール、ここでは上記のソリューション。これにはタイムゾーンだけでなく、中央ヨーロッパも含まれていることに注意してください。中央ヨーロッパでは、4月の最終日曜日と10月の最終日曜日が続きます。また、2006年の米国は4月の古い最初の日曜日、10月の規則の最後の日曜日に続くことにも気付くでしょう。

このSQLコードは少し見苦しいかもしれませんが、コピーしてSQL Serverに貼り付けて試してください。年、タイムゾーン、ルールの3つのセクションがあることに注意してください。別の年が必要な場合は、それを年の組合に追加してください。別のタイムゾーンまたはルールについても同じです。

select yr, zone, standard, daylight, rulename, strule, edrule, yrstart, yrend,
    dateadd(day, (stdowref + stweekadd), stmonthref) dstlow,
    dateadd(day, (eddowref + edweekadd), edmonthref)  dsthigh
from (
  select yrs.yr, z.zone, z.standard, z.daylight, z.rulename, r.strule, r.edrule, 
    yrs.yr + '-01-01 00:00:00' yrstart,
    yrs.yr + '-12-31 23:59:59' yrend,
    yrs.yr + r.stdtpart + ' ' + r.cngtime stmonthref,
    yrs.yr + r.eddtpart + ' ' + r.cngtime edmonthref,
    case when r.strule in ('1', '2', '3') then case when datepart(dw, yrs.yr + r.stdtpart) = '1' then 0 else 8 - datepart(dw, yrs.yr + r.stdtpart) end
    else (datepart(dw, yrs.yr + r.stdtpart) - 1) * -1 end stdowref,
    case when r.edrule in ('1', '2', '3') then case when datepart(dw, yrs.yr + r.eddtpart) = '1' then 0 else 8 - datepart(dw, yrs.yr + r.eddtpart) end
    else (datepart(dw, yrs.yr + r.eddtpart) - 1) * -1 end eddowref,
    datename(dw, yrs.yr + r.stdtpart) stdow,
    datename(dw, yrs.yr + r.eddtpart) eddow,
    case when r.strule in ('1', '2', '3') then (7 * CAST(r.strule AS Integer)) - 7 else 0 end stweekadd,
    case when r.edrule in ('1', '2', '3') then (7 * CAST(r.edrule AS Integer)) - 7 else 0 end edweekadd
from (
    select '2005' yr union select '2006' yr -- old us rules
    UNION select '2007' yr UNION select '2008' yr UNION select '2009' yr UNION select '2010' yr UNION select '2011' yr
    UNION select '2012' yr UNION select '2013' yr UNION select '2014' yr UNION select '2015' yr UNION select '2016' yr
    UNION select '2017' yr UNION select '2018' yr UNION select '2018' yr UNION select '2020' yr UNION select '2021' yr
    UNION select '2022' yr UNION select '2023' yr UNION select '2024' yr UNION select '2025' yr UNION select '2026' yr
) yrs
cross join (
    SELECT 'ET' zone, '-05:00' standard, '-04:00' daylight, 'US' rulename
    UNION SELECT 'CT' zone, '-06:00' standard, '-05:00' daylight, 'US' rulename
    UNION SELECT 'MT' zone, '-07:00' standard, '-06:00' daylight, 'US' rulename
    UNION SELECT 'PT' zone, '-08:00' standard, '-07:00' daylight, 'US' rulename
    UNION SELECT 'CET' zone, '+01:00' standard, '+02:00' daylight, 'EU' rulename
) z
join (
    SELECT 'US' rulename, '2' strule, '-03-01' stdtpart, '1' edrule, '-11-01' eddtpart, 2007 firstyr, 2099 lastyr, '02:00:00' cngtime
    UNION SELECT 'US' rulename, '1' strule, '-04-01' stdtpart, 'L' edrule, '-10-31' eddtpart, 1900 firstyr, 2006 lastyr, '02:00:00' cngtime
    UNION SELECT  'EU' rulename, 'L' strule, '-03-31' stdtpart, 'L' edrule, '-10-31' eddtpart, 1900 firstyr, 2099 lastyr, '01:00:00' cngtime
) r on r.rulename = z.rulename
    and datepart(year, yrs.yr) between firstyr and lastyr
) dstdates

ルールでは、最初、2番目、3番目、または最後の日曜日に1、2、3またはLを使用します。日付部分は月を示し、ルールに応じて、ルールタイプLの月の最初の日または月の最後の日を示します。

上記のクエリをビューに入れました。これで、タイムゾーンオフセット付きの日付またはUTC時間に変換された日付が必要なときはいつでも、このビューに参加し、日付形式で日付を取得することを選択します。日時の代わりに、これらをdatetimeoffsetに変換しました。

select createdon, dst.zone
    , case when createdon >= dstlow and createdon < dsthigh then dst.daylight else dst.standard end pacificoffsettime
    , TODATETIMEOFFSET(createdon, case when createdon >= dstlow and createdon < dsthigh then dst.daylight else dst.standard end) pacifictime
    , SWITCHOFFSET(TODATETIMEOFFSET(createdon, case when createdon >= dstlow and createdon < dsthigh then dst.daylight else dst.standard end), '+00:00')  utctime
from (select '2014-01-01 12:00:00' createdon union select '2014-06-01 12:00:00' createdon) photos
left join US_DAYLIGHT_DATES dst on createdon between yrstart and yrend and zone = 'PT'
5
Chris Barlow

これが私の汚いバージョンです。私はすべての日付が米国東部時間帯を使用していたことを知っています。オフセットを変更するか、必要に応じてよりスマートにすることができます。 1回限りの移行を行っていたので、これで十分でした。

CREATE FUNCTION [dbo].[ConvertToUtc]
(
    @date datetime
)
RETURNS DATETIME
AS
BEGIN
    -- Declare the return variable here
    DECLARE @utcDate datetime;
    DECLARE @offset int;

    SET @offset = (SELECT CASE WHEN 
                                    @date BETWEEN '1987-04-05 02:00 AM' AND '1987-10-25 02:00 AM'
                                 OR @date BETWEEN '1988-04-03 02:00 AM' AND '1988-10-30 02:00 AM'
                                 OR @date BETWEEN '1989-04-02 02:00 AM' AND '1989-10-29 02:00 AM'
                                 OR @date BETWEEN '1990-04-01 02:00 AM' AND '1990-10-28 02:00 AM'
                                 OR @date BETWEEN '1991-04-07 02:00 AM' AND '1991-10-27 02:00 AM'
                                 OR @date BETWEEN '1992-04-05 02:00 AM' AND '1992-10-25 02:00 AM'
                                 OR @date BETWEEN '1993-04-04 02:00 AM' AND '1993-10-31 02:00 AM'
                                 OR @date BETWEEN '1994-04-03 02:00 AM' AND '1994-10-30 02:00 AM'
                                 OR @date BETWEEN '1995-04-02 02:00 AM' AND '1995-10-29 02:00 AM'
                                 OR @date BETWEEN '1996-04-07 02:00 AM' AND '1996-10-27 02:00 AM'
                                 OR @date BETWEEN '1997-04-06 02:00 AM' AND '1997-10-26 02:00 AM'
                                 OR @date BETWEEN '1998-04-05 02:00 AM' AND '1998-10-25 02:00 AM'
                                 OR @date BETWEEN '1999-04-04 02:00 AM' AND '1999-10-31 02:00 AM'
                                 OR @date BETWEEN '2000-04-02 02:00 AM' AND '2000-10-29 02:00 AM'
                                 OR @date BETWEEN '2001-04-01 02:00 AM' AND '2001-10-28 02:00 AM'
                                 OR @date BETWEEN '2002-04-07 02:00 AM' AND '2002-10-27 02:00 AM'
                                 OR @date BETWEEN '2003-04-06 02:00 AM' AND '2003-10-26 02:00 AM'
                                 OR @date BETWEEN '2004-04-04 02:00 AM' AND '2004-10-31 02:00 AM'
                                 OR @date BETWEEN '2005-04-03 02:00 AM' AND '2005-10-30 02:00 AM'
                                 OR @date BETWEEN '2006-04-02 02:00 AM' AND '2006-10-29 02:00 AM'
                                 OR @date BETWEEN '2007-03-11 02:00 AM' AND '2007-11-04 02:00 AM'
                                 OR @date BETWEEN '2008-03-09 02:00 AM' AND '2008-11-02 02:00 AM'
                                 OR @date BETWEEN '2009-03-08 02:00 AM' AND '2009-11-01 02:00 AM'
                                 OR @date BETWEEN '2010-03-14 02:00 AM' AND '2010-11-07 02:00 AM'
                                 OR @date BETWEEN '2011-03-13 02:00 AM' AND '2011-11-06 02:00 AM'
                                 OR @date BETWEEN '2012-03-11 02:00 AM' AND '2012-11-04 02:00 AM'
                                 OR @date BETWEEN '2013-03-10 02:00 AM' AND '2013-11-03 02:00 AM'
                                 OR @date BETWEEN '2014-03-09 02:00 AM' AND '2014-11-02 02:00 AM'
                                 OR @date BETWEEN '2015-03-08 02:00 AM' AND '2015-11-01 02:00 AM'
                                 OR @date BETWEEN '2016-03-13 02:00 AM' AND '2016-11-06 02:00 AM'
                                 OR @date BETWEEN '2017-03-12 02:00 AM' AND '2017-11-05 02:00 AM'
                                 OR @date BETWEEN '2018-03-11 02:00 AM' AND '2018-11-04 02:00 AM'
                                 OR @date BETWEEN '2019-03-10 02:00 AM' AND '2019-11-03 02:00 AM'
                                 OR @date BETWEEN '2020-03-08 02:00 AM' AND '2020-11-01 02:00 AM'
                                 OR @date BETWEEN '2021-03-14 02:00 AM' AND '2021-11-07 02:00 AM'
                               THEN 4
                               ELSE 5 END);

    SELECT @utcDate = DATEADD(hh, @offset, @date)
    RETURN @utcDate;

END
2
AndyMcKenna

上記の可能性を逃さない限り、上記のすべての方法は、夏時間(EDTなど)から標準時(ESTなど)に切り替える際に重複をとらないという点で欠陥があります。 (非常に詳細な)例:

[1] EDT 2016-11-06 00:59 - UTC 2016-11-06 04:59
[2] EDT 2016-11-06 01:00 - UTC 2016-11-06 05:00
[3] EDT 2016-11-06 01:30 - UTC 2016-11-06 05:30
[4] EDT 2016-11-06 01:59 - UTC 2016-11-06 05:59
[5] EST 2016-11-06 01:00 - UTC 2016-11-06 06:00
[6] EST 2016-11-06 01:30 - UTC 2016-11-06 06:30
[7] EST 2016-11-06 01:59 - UTC 2016-11-06 06:59
[8] EST 2016-11-06 02:00 - UTC 2016-11-06 07:00

日付と時刻に基づく単純な時間オフセットは、それを削減しません。現地時間が01:00から01:59の間にEDTまたはESTで記録されたかどうかわからない場合、手がかりはありません!たとえば、01:30を使用してみましょう。01:31から01:59の範囲で後の時間を見つけた場合、見ている01:30が[3または[6。この場合、以前のエントリを見て少しのコーディングで正しいUTC時間を取得できます(SQLでは面白くありません)、これが最良のケースです...

次の現地時間が記録されており、EDTまたはESTを示すために少しも専念しなかったとします。

                     UTC time         UTC time         UTC time
                     if [2] and [3]   if [2] and [3]   if [2] before
local time           before switch    after switch     and [3] after
[1] 2016-11-06 00:43     04:43         04:43           04:43
[2] 2016-11-06 01:15     05:15         06:15           05:15
[3] 2016-11-06 01:45     05:45         06:45           06:45
[4] 2016-11-06 03:25     07:25         07:25           07:25

時間[2]と[3]は、午前5時、午前6時、または午前5時と午前6時の間にあります。 。 。言い換えれば、あなたはうんざりしており、01:00:00から01:59:59までのすべての測定値を捨てなければなりません。この状況では、実際のUTC時間を解決する方法はまったくありません!

1
Gil

以下は、実行中のサーバーのDATEとUTCDATEの差を計算し、そのオフセットを使用して、渡された日付に相当するUTCを計算するため、機能するはずです。私の例では、オーストラリアのアデレードでUTCオフセットが-630分である「1-nov-2012 06:00」のUTC相当を変換しようとしています。これは、任意の日付に追加すると、現地日付のUTC相当になります。

選択DATEADD(MINUTE、DATEDIFF(MINUTE、GETDATE()、GETUTCDATE())、 '1-nov-2012 06:00')

0
Gaurav Arora

誰かがこれに出くわし、Chris Barlowの答えを使用した場合、2018が2回リストされるタイプミスがあり、2回目は2019になるはずです。具体的にはこの行:

   UNION select '2017' yr UNION select '2018' yr UNION select '2018' yr UNION select '2020' yr UNION select '2021' yr

クリスの答えについてコメントするのに十分なポイントがありません。それ以外は、答えは素晴らしいです!

0
Brian Woelfel

ServerZone DateTimeをUTCに、UTCをServerZone DateTimeに変換できます

次のスクリプトを実行して変換を理解し、必要に応じて変更します

--Get Server's TimeZone
DECLARE @ServerTimeZone VARCHAR(50)
EXEC MASTER.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
'SYSTEM\CurrentControlSet\Control\TimeZoneInformation',
'TimeZoneKeyName',@ServerTimeZone OUT

-- ServerZone to UTC DATETIME
DECLARE @CurrentServerZoneDateTime DATETIME = GETDATE()
DECLARE @UTCDateTime  DATETIME =  @CurrentServerZoneDateTime AT TIME ZONE @ServerTimeZone AT TIME ZONE 'UTC' 
--(OR)
--DECLARE @UTCDateTime  DATETIME = GETUTCDATE()
SELECT @CurrentServerZoneDateTime AS CURRENTZONEDATE,@UTCDateTime AS UTCDATE

-- UTC to ServerZone DATETIME
SET @CurrentServerZoneDateTime = @UTCDateTime AT TIME ZONE 'UTC' AT TIME ZONE @ServerTimeZone
SELECT @UTCDateTime AS UTCDATE,@CurrentServerZoneDateTime AS CURRENTZONEDATE

:これ(AT TIME ZONESQL Server 2016+のみで動作この利点は、特定のタイムゾーンに変換する際に自動的にDaylightを考慮する

0
KarthikeyanMlp

どれくらい前に戻る必要があるかに応じて、夏時間のテーブルを作成し、テーブルに参加してdstに敏感な変換を行うことができます。この特定のものは、ESTからGMTに変換します(つまり、5と4のオフセットを使用します)。

select createdon, dateadd(hour, case when dstlow is null then 5 else 4 end, createdon) as gmt
from photos
left outer join (
          SELECT {ts '2009-03-08 02:00:00'} as dstlow, {ts '2009-11-01 02:00:00'} as dsthigh
UNION ALL SELECT {ts '2010-03-14 02:00:00'} as dstlow, {ts '2010-11-07 02:00:00'} as dsthigh
UNION ALL SELECT {ts '2011-03-13 02:00:00'} as dstlow, {ts '2011-11-06 02:00:00'} as dsthigh
UNION ALL SELECT {ts '2012-03-11 02:00:00'} as dstlow, {ts '2012-11-04 02:00:00'} as dsthigh
UNION ALL SELECT {ts '2013-03-10 02:00:00'} as dstlow, {ts '2013-11-03 02:00:00'} as dsthigh
UNION ALL SELECT {ts '2014-03-09 02:00:00'} as dstlow, {ts '2014-11-02 02:00:00'} as dsthigh
UNION ALL SELECT {ts '2015-03-08 02:00:00'} as dstlow, {ts '2015-11-01 02:00:00'} as dsthigh
UNION ALL SELECT {ts '2016-03-13 02:00:00'} as dstlow, {ts '2016-11-06 02:00:00'} as dsthigh
UNION ALL SELECT {ts '2017-03-12 02:00:00'} as dstlow, {ts '2017-11-05 02:00:00'} as dsthigh
UNION ALL SELECT {ts '2018-03-11 02:00:00'} as dstlow, {ts '2018-11-04 02:00:00'} as dsthigh
    ) dst
    on createdon >= dstlow and createdon < dsthigh
0
Warren