sql >> データベース >  >> RDS >> Oracle

日付データ型のEquals(=)とLIKE

    LAST_TRANSACTION_DATEを想定 DATEです 列(またはTIMESTAMP )その後、両方のバージョンは非常に悪い習慣です。

    どちらの場合も、DATE 列は、現在のNLS設定に基づいて暗黙的に文字リテラルに変換されます。つまり、クライアントが異なれば、結果も異なります。

    日付リテラルを使用する場合常に to_date()を使用する with(!)フォーマットマスクまたはANSI日付リテラルを使用します。このようにして、日付を文字列と文字列ではなく日付と比較します。したがって、同等の比較を行うには、次を使用する必要があります:

    LAST_TRANSACTION_DATE = to_date('30-JUL-07', 'dd-mon-yy')
    

    'MON'を使用すると、異なるNLS設定('DEC')でエラーが発生する可能性があることに注意してください。 vs. 'DEZ' または'MAR' vs. 'MRZ' )。月番号(および4桁の年)を使用すると、エラーが発生しにくくなります。

    LAST_TRANSACTION_DATE = to_date('30-07-2007', 'dd-mm-yyyy')
    

    またはANSI日付リテラルを使用する

    LAST_TRANSACTION_DATE = DATE '2007-07-30'
    

    上記のクエリが何も返さない可能性が非常に高い理由は、OracleのDATEにあるためです。 列には時間も含まれます。上記の日付リテラルには、暗黙的に時刻00:00が含まれています 。テーブル内の時間が異なる場合(例:19:54 )そしてもちろん、日付は等しくありません。

    この問題を回避するには、さまざまなオプションがあります。

    1. trunc()を使用する テーブルの列で、時間を00:00に「正規化」します trunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30 ただし、これにより、LAST_TRANSACTION_DATEで定義されたインデックスを使用できなくなります。
    2. betweenを使用する
      LAST_TRANSACTION_DATE between to_date('2007-07-30 00:00:00', 'yyyy-mm-dd hh24:mi:ss') and to_date('2007-07-30 23:59:59', 'yyyy-mm-dd hh24:mi:ss')

    最初のソリューションのパフォーマンスの問題は、trunc(LAST_TRANSACTION_DATE)にインデックスを作成することで回避できます。 その式で使用できます。ただし、式LAST_TRANSACTION_DATE = '30-JUL-07' 内部的にはto_char(LAST_TRANSACTION_DATE) = '30-JUL-07'として処理されるため、インデックスの使用も防止します。

    覚えておくべき重要なこと:

    1. 暗黙のデータ型変換に依存しないでください。 ある時点で問題が発生します。常に正しいデータ型を比較してください
    2. Oracle DATE 列には常に、比較ルールの一部である時間が含まれています。


    1. SpotlightCloudをセットアップしてSQLServerを効率的にトラブルシューティングする方法

    2. Access2016でレポートをグループ化する方法

    3. MySQLの文字列から不要な先頭文字を削除する方法

    4. SQLでゼロ除算を処理する方法