1

テーブルに INT 列があります。この列には、日付が特別な形式で格納されます。その列をDATE型に変換しようとしています。

たとえば、 として保持'2016-03-14'20160314ます。

例外として、各月の最終日は日を保存しません。そのため、'2016-03-31'私たちが保存しているため、数字が月末または月の他の日を表すか201603どうかを検討する必要があります。less than 999999

これまでのところ、このタスクを達成するために 2 つのクエリがあります。

クエリ 1:

これはすべて数学の公式です。

declare @k int = 20160321
--declare @k int = 201603
select 
    IIF(@k < 999999
        , EOMONTH(DATEFROMPARTS(@k /100, @k % 100, 1), 0)
        , DATEFROMPARTS(@k /10000, (@k / 100) % 100, @k % 100)
    )

クエリ 2: これは文字列操作を使用しています。

declare @k int = 20160321
--declare @k int = 201603

select 
    IIF(@k < 999999
        , EOMONTH(cast(LEFT(@k, 4) + '-' + RIGHT(@k, 2) + '-01'  as date), 0)
        , cast(LEFT(@k, 4) + '-' + RIGHT(LEFT(@k, 6), 2) + '-' + RIGHT(@k, 2) as date )
    ) AS DateColumn

WHERE節で変換式を実行する必要があります。何かのようなもの:

SELECT K, Dt, Name -- and more fields
FROM tbl
WHERE IIF(K < 999999
            , EOMONTH(DATEFROMPARTS(K /100, K % 100, 1), 0)
            , DATEFROMPARTS(K /10000, (K / 100) % 100, K % 100)
        ) < GetDate()

performance is important

質問: これを行うためのより良い方法はありますか? おそらく、SQL Server が K 列にあるクラスター化インデックスを使用できる方法です。

4

1 に答える 1

1

クエリ 1 のパフォーマンスが向上すると予想されますが、確実にテストする必要があります。どのような性能datefromparts()datetimefromparts()持っているかわかりません。それらは比較的新しいものなので、正当な理由もなく魔法のようにひどいものだったとしても、私はショックを受けません. 文字列操作と型キャストのパフォーマンスと、算術と型キャストのパフォーマンスを比較しています。私の推測では、ほとんどがウォッシュですが、その演算はおそらく高速です。

ソリューションのパフォーマンスに関して私を驚かせるオプションは次のとおりです。 a) datetime 列をテーブルに追加します。b) 計算列をテーブルに追加します。PERSISTED 列を作成すると、それに索引を作成することもできます。c) ビューを作成します (要件のフープをジャンプできる場合は、インデックス付きビュー)。d) 日時フィールドを含む新しいテーブルを作成し、更新します。

(a) と (d) はどちらもデータが重複しているため、最初に表示されたほど優れたソリューションではありません。

計算列は少し大雑把だといつも思っていましたが、十分に機能します。ビューを作成した場合、それを使用するには内部結合する必要がありますが、ほとんどのシステムでは、結合は非常に高速です。

おそらく、永続化された計算列またはビューの作成を検討するでしょう。もちろん、最善の解決策は、最初から日付を整数として格納しないことです。


次のクエリを試すことができます。

SELECT CASE 
        WHEN @K < 999999 THEN EOMONTH(TRY_CONVERT(date, CAST(@K * 100 + 1 AS VARCHAR(10))))
        ELSE TRY_CONVERT(date, CAST(@K AS VARCHAR(10)))
    END AS K_Date

これが機能する理由YYYYMMDDは、ISO 日付形式の 1 つであるためです。クエリエンジンは、条件を確認せずにすべてを評価してエラーをスローすることを決定できるため、TRY_CONVERT()前に試してみました。CONVERT()CONVERTCASE

于 2016-04-27T21:26:54.377 に答える