SQLで日付を比較するクエリ


83

11月にすべて発生した日付の表があります。私はこのクエリを書きました

select id,numbers_from,created_date,amount_numbers,SMS_text 
from Test_Table
where 
created_date <= '2013-04-12'

このクエリは、日付「2013-04-12」(12月)より前に発生したため、11月(11月)に発生したすべてを返す必要があります。

しかし、それだけでよりも少ない日に起こったことを利用できる日数を返します04(2013- 04 -12)

日の部分だけを比較しているのでしょうか?日付全体ではありませんか?

これを修正する方法は?

Created_dateはdateです

日付形式はデフォルトでyyyy-dd-MMです


1
日付と日付ではなく、日付と文字列を比較しています
Panagiotis Kanavos 2013年

4
多分それは思い2013-04-12ますか?4月12日ですか?それともcreated_date、日付ではなく文字列ですか?
jpw 2013年

T-SQLマニュアルのCast&Convertを見て、ロケールに適した変換を使用してください
Steve

3
キャストする必要はまったくありません。不変形式「20130412」を使用するだけです
Panagiotis Kanavos 2013年

1
日付を含む文字列を送信する代わりに、パラメータ化されたクエリを作成して、日付を日付型パラメータとして渡します。ところで、どのバージョンのSQL Serverを使用していますか?DATEは、SQL Server 2008で追加されました
パナギオティスKanavos

回答:


82

地域の文化に応じて意味が異なる「2013-04-12」の代わりに、文化不変形式として認識されている「20130412」を使用してください。

あなたは12月4日と比較したい場合は番目の、あなたは「20131204」を書き込む必要があります。あなたが4月12日と比較したい場合は番目の、あなたは「20130412」を書き込む必要があります。

SQLServerのドキュメントの「WriteInternationalTransact-SQL Statements」の記事では、カルチャに依存しないステートメントの記述方法について説明しています。

他のAPI、またはTransact-SQLスクリプト、ストアドプロシージャ、トリガーを使用するアプリケーションでは、区切りのない数値文字列を使用する必要があります。たとえば、yyyymmddは19980924です。

編集

ADOを使用しているため、クエリをパラメーター化し、日付値を日付パラメーターとして渡すのが最善のオプションです。このようにして、フォーマットの問題を完全に回避し、パラメーター化されたクエリのパフォーマンス上の利点も得られます。

更新

リテラルでISO8601形式を使用するには、すべての要素を指定する必要があります。datetimeのドキュメントのISO8601セクションから引用するには

ISO 8601形式を使用するには、形式の各要素を指定する必要があります。これには、形式で表示されるT、コロン(:)、およびピリオド(。)も含まれます。

... 2番目のコンポーネントの端数はオプションです。時間コンポーネントは24時間形式で指定されます。


@andy正確ではありませんが、ISO8601形式は時間要素が含まれています。または、ドキュメントにあるようにTo use the ISO 8601 format, you must specify each element in the format. This also includes the T
Panagiotis Kanavos 2015

1
不明確で申し訳ありませんが、私のポイントは、ISO8601があなたが説明したとおりに順序を定義しているということでした:YYYY-MM-DDまたは略してYYYYMMDD。ただし、ドキュメントにも記載されているように、「日時はANSIまたはISO8601に準拠していません。」ISO自体は時間の部分を必要としません。
andy 2015

あなたが参照することYYYY-MM-DDは、ISO8601として認識されていないという事実を変えることはありません。時間の部分必要です。必要に応じて、T-SQLの奇妙さ、または不完全な実装と呼んでください。これはSybaseから引き継がれた可能性もあります
Panagiotis Kanavos

31

このようにしてみてください

select id,numbers_from,created_date,amount_numbers,SMS_text 
from Test_Table
where 
created_date <= '2013-12-04'

6
カルチャ固有の形式。それは4月12日ですか、それとも12月4日ですか。ダッシュで区切られた形式は国際形式ではありません
Panagiotis Kanavos 2013年

1
では、国際的なクライアントからのデータを保存する必要がある場合はどうなりますか?または、日付はユーザーの文化に従ったWebブラウザーから取得されますか?ガイドラインには理由があり、間違った形式を使用しないことで、すべてのエラーを回避できます
Panagiotis Kanavos 2013年

1
@Nitheshこれは4月12日に戻ってきます
HelpASisterOut 2013年

17
@PanagiotisKanavosダッシュ区切り形式、1988年にISO 8601が公開されて以来、国際的な形式です。他の形式は推奨されておらず、嘲笑されています。あなたが投稿した記事「WriteInternationalTransact -SQL Statements」でさえ、「yyyymmdd」をあらゆる種類の「国際」標準として一度も識別していません。
Jesse Webb

2
日付の前後に一重引用符を追加すると、これが解決しました。フォーマット2/19/2015を使用していました。「2015年2月19日」に変更され、動作を開始しました。シンプルなアイデアをありがとう。
イーサンターク

9

日付値のみと比較している場合は、それを日付(日時ではなく)に変換すると機能します

select id,numbers_from,created_date,amount_numbers,SMS_text 
 from Test_Table
 where 
 created_date <= convert(date,'2013-04-12',102)

この変換は、GetDate()関数の使用中にも適用できます。


4

あなたが置く<=と、それも与えられた日付をキャッチします。と交換でき<ます。


2

以下のクエリで試してください

select id,numbers_from,created_date,amount_numbers,SMS_text 
from Test_Table
where 
convert(datetime, convert(varchar(10), created_date, 102))  <= convert(datetime,'2013-04-12')

0

日付形式はyyyy-mm-ddです。したがって、上記のクエリは2013年4月12日より古いレコードを探しています

日付文字列を「2013-04-30」に設定して簡単なチェックを行うことをお勧めします。SQLエラーがない場合、日付形式はyyyy-mm-ddに確認されます。


0

日付の前後に「#」を使用し、システムの日付形式を確認してください。多分 "YYYYMMDD O YYYY-MM-DD O MM-DD-YYYY O USING '/ O \'"

例:

 select id,numbers_from,created_date,amount_numbers,SMS_text 
 from Test_Table
 where 
 created_date <= #2013-04-12#
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.