4

次のコードの where 句ステートメントをクリーンアップしようとしています。

SELECT
    CONVERT(datetime, [UTC_Time_Stamp], 127) AS TimeStamp
FROM 
    Table 
WHERE 
    CASE 
       WHEN ISDATE([UTC_Time_Stamp]) = 1 
       THEN CONVERT(datetime, [UTC_Time_Stamp], 127) 
       ELSE CAST('1/1/1900' AS datetime) 
    END > CAST('11/09/2012' AS datetime) 
    AND 
       CASE 
          WHEN ISDATE([UTC_Time_Stamp]) = 1 
          THEN CONVERT(datetime, [UTC_Time_Stamp], 127) 
          ELSE CAST('1/1/3000' AS datetime) 
       END < CAST('11/10/2012' as datetime) 
ORDER BY 
    TimeStamp;

UTC_Time_Stamp文字列として保存され、null の場合もあります。以前、where 句内で変換エラーが発生していました。this question hereのアドバイスに従ってエラーを修正しましたが、同じ結果を得るにはもっと簡単な方法が必要だと思います。

4

4 に答える 4

4

ステートメント内で変換を行う必要があります。caseSQL は記述言語であり、処理の順序を保証するものではありません。そのため、where句がサブクエリまたは CTE にある場合でも、句は必ずしも他の処理の前に発生するとは限りません。ただし、SQL はcaseステートメント (集計関数を含む式を含まない) での処理の順序を保証します。

サブクエリを使用すると、ステートメントを簡素化できます。

select TimeStamp
FROM (select t.*,
             Case When ISDATE([UTC_Time_Stamp]) = 1 Then CONVERT(datetime, UTC_Time_Stamp, 127) end) as TimeStamp
      from Table t
     ) t
WHERE coalesce(TimeStamp, cast('1/1/1900' as datetime)) > cast('11/09/2012' as datetime) and
      coalesce(TimeStamp, cast('1/1/3000' as datetime)) < cast('11/10/2012' as datetime) 
ORDER BY TimeStamp;

これにより、有効な値の TimeStamp への変換が行われます。その後、外側のクエリで変数を使用できます。

また、'11/10/2012' のようなあいまいな形式ではなく、日付の ANSI 標準形式 (YYYYMMDD または YYYY-MM-DD) に慣れることをお勧めします。これが 2012-11-10 を意味することは明らかです。. . またはそれは 2012-10-11 です。. . しかし、形式があいまいです。

于 2012-11-12T16:54:47.960 に答える
1

これにはCTEが好きです。または、一時テーブル、テーブル変数、または@Derekのようなインライン派生テーブルを作成することもできます.

基本的に、最初に適切なデータ型を取得してから、クエリを作成しやすくします。

;with CTE as (
    -- Bring back the column as datetime
    select case when isdate(UTC_Time_Stamp) = 1 then cast(UTC_Time_Stamp as datetime) end as UTC_Time_Stamp
    from [Table]
)
-- Simple select with the proper datatype
select convert(varchar(50), UTC_Time_Stamp, 127) as [TimeStamp]
from CTE
-- May still need gt and lt functionality
where UTC_Time_Stamp between cast('11/09/2012' as datetime) and cast('11/10/2012' as datetime)

日付以外の場合、 TimeStamp に任意の小さい値と大きい値を使用しているようですが、これはおそらく比較を考えると不要なので、それらを削除しました。

CTE と比較のために datetime データ型を使用していることに注意してください。表示用の文字列に変換するだけです。

また、これは包括的であるため、別の節とwhere 節betweenに戻る必要があるかもしれないことに注意してください。><

于 2012-11-12T16:51:56.293 に答える
0

次のようなことを行う方が簡単です (適切と思われる述語で convert/ between 句を使用します):

SELECT CONVERT(datetime, [UTC_Time_Stamp], 127) as TimeStamp
FROM (
  select [UTC_Time_Stamp] 
  from Table 
  WHERE ISDATE([UTC_Time_Stamp]) = 1 
) a
WHERE
  convert(datetime, [UTC_Time_Stamp], 127) between '11/9/2012' and '11/10/2012'
ORDER BY TimeStamp;
于 2012-11-12T16:40:13.793 に答える