1

私はテーブルを持っています

NUM | TDATE   
1   | 200712    
2   | 200708    
3   | 200704    
4   | 20081210

mytableとして作成される場所

 mytable
(
  num int,
  tdate char(8)  -- legacy 
);

tdate の形式は YYYYMMDD です。このdate部分はオプションの場合もあります。
したがって、「200712」などの日付は 2007-12-01 と解釈できます。

tdate日付列として扱い、日付比較を適用できるようなクエリを書きたいと思います。

お気に入り

select num, tdate from mytable where tdate  

between '2007-12-31 00:00:00' and '2007-05-01 00:00:00'

これまでのところ、私はこれを試しました

select num, tdate,
CAST(LEFT(tdate,6) 
+ COALESCE(NULLIF(SUBSTRING(CAST(tdate AS VARCHAR(8)),7,8),''),'01') AS Date)
from mytable 

SQL フィドル

上記の変換された日付 (3 列目) を比較に使用するにはどうすればよいですか? (参加が必要ですか?)

また、これを行うためのより良い方法はありますか?

編集: 今のところ、テーブル スキームを制御することはできません..DB チームに変更を提案しました..今のところ、 char(8) に固執する必要があります。

4

7 に答える 7

1

文字列値を日付に変換するさらに別の方法は、次を使用することREPLACEです。

SELECT num, tdate
FROM mytable
WHERE CAST(REPLACE(tdate, '  ', '01') AS date) BETWEEN @date1 AND @date2
;

date変換された値返し、それをフィルタリングに使用したい場合はCROSS APPLY、ロジックの繰り返しを避けるために採用できます。

SELECT t.num, t.tdate, x.date
FROM mytable AS t
CROSS APPLY (SELECT CAST(REPLACE(t.tdate, '  ', '01') AS date)) AS x (date)
WHERE x.date BETWEEN @date1 AND @date2
;

char(8)このメソッドは、文字列が または のいずれYYYYMMDDかとしてフォーマットされていることを前提としていますが、他の 2 つのフォーマットに加えてYYYYMMとしてフォーマットされた値の使用を開始することにした場合、このメソッドは変更なしで機能します (年の始まりを意味するため、 aが意味するのと同じように)月初め)。YYYYYYYYMM

于 2013-09-02T10:02:38.253 に答える
1

'2007-12-31 00:00:00'>'2007-05-01 00:00:00'であるため、BETWEEN句がレコードを返すことはありません。

これは、サブクエリを使用し、日付を反転して機能します。

select num, tdate, formattedDate
from 
(
  select num, tdate
  ,
  CAST(LEFT(tdate,6) + COALESCE(NULLIF(SUBSTRING(CAST(tdate AS VARCHAR(8)),7,8),''),'01') AS Date) as formattedDate

  from mytable 
) a
where formattedDate between '2007-05-01 00:00:00' and '2007-12-31 00:00:00'

sqlFiddle ここ

于 2013-08-29T16:44:31.093 に答える
0

私の提案は、テーブルに日付フィールドを追加することです。テーブルが定期的に更新される場合は、定期的なスケジュール (トリガーまたはジョブ) でストアド プロシージャを介して従来のフィールドから入力します。

そうすれば、混乱、間違い、疑わしい結果の潜在的な原因となるこれらすべてのトリック、ターンアラウンド、およびその他の概算なしで、日付を ... として使用できるようになります。

于 2013-08-29T16:53:56.517 に答える