タイムスタンプとして格納された誕生日のためのリストを返すためのデータベースに依存しないSQL
-
22-08-2019 - |
質問
私は日付が唯一の日に一致したすべての行を返すための最良の方法は何か時間と分を含んで検索する必要があり、時間と分が、日付なしで保存されている出産の日、月に検索する必要がある場合年
すなわち。
01-JAN-50 10.22.06.000000000
として保存
日付が選択された01-JAN-50 10.22.06.010101120
SQLはちょうど日、月、年のためにそれらの正確なタイムスタンプを持つ行を返しません。
SQLは、Oracle、SQLServerのは、MySQLとDB2で作業する必要があります。
解決
OracleのDATE型は、これは非常に困難にSQL標準バージョンを(Informixの者が行うように)、事前にさかのぼります。もちろん、「なぜ選ばれたデータ表現は、時間を含まない」の質問があります。
標準SQLでは、明白な技術はDATEにTIMESTAMPをキャストすることです。我々はまた、あなたが検索する必要があり、データの明確な説明はありません。
SELECT CAST(DateOfBirth AS DATE), ...other columns...
FROM TheMysteryTable -- Why do people hate giving tables names?
WHERE CAST(DateOfBirth AS DATE) =
CAST(TIMESTAMP '1950-01-01 10.22.06.010101120' AS DATE)
しかし、それはあなたがリテラルとして「で検索する日付」を書くことを想定しています。それはホスト変数である場合には、ホスト変数の型がDATE、TIMESTAMPではないはずです。そしてdateOfBirthの列は、おそらくDATE、TIMESTAMPではないはずです。時刻部分が関連している場合を除き、あなたは、TIMESTAMPを使用してはならない - それは、ストレージを浪費し、それが計算時間を浪費
。キャストのため、DBMSは、すべてのインデックスか何かを使用できるようになることはほとんどありませんので注意してください。種類が正気だった場合は、クエリは、単純になります:
SELECT DateOfBirth, ...other columns...
FROM TheMysteryTable
WHERE DateOfBirth = DATE '1950-01-01'
他のヒント
、次に何システムにとらわれないソリューションは存在しないであろう - それぞれがこれらのオブジェクトの異なる機能を有することになる
。データベース抽象化以外の最善の解決策は、その後だけ汎用のSQL比較句は、リストされたすべてのDBに機能される必要があり、最初に使用されるDateTimeオブジェクトを丸めることであろう。
何のANSIの日付書式、また文字列操作はありません。 1つだけでなく場合は、任意のコードが、RDBMS年代特定にのみ実行されます。
しかし、あなたは(たとえば、PHPは、Java等は、)、私は、クエリでそれを送信する前にそれを消毒することをお勧めしたいあなたのRDBMSの外にあなたの選択した日付を取得している場合。あなたは、ほぼすべてのシステムで動作するはずの文字列に文字列を比較することができます。
、RDBMSののは非常に発散しています。 の場合はを、彼らは実際には、次の動作するはず、ANSI-92標準に従っます:
SELECT
<column list>
FROM
<table name>
WHERE
CAST(birth_date AS DATE) = CAST(search_date AS DATE)
それはほとんどのシステムの日付のインデックスを使用して妨げるので、ザ・が、しかしそれを行うための最も効率的な方法ではないでしょう。完全にANSI-92準拠のデータベースに対して次の可能性がありますの仕事ます:
SELECT
<column list>
FROM
<table name>
WHERE
birth_date >= CAST(CAST(search_date AS DATE) AS DATETIME) AND
birth_date < CAST(CAST(search_date AS DATE) + 1 AS DATETIME)
を使用EXTRACT()