2017-09-27 14 views
0

問題: 私はDECODEという名前の関数としてクエリを解読しています。私は構文(列、値、置換値、デフォルト)を見上げたが、私は以下の構文が何をしているのかを理解していない。Oracle DECODE構文

問合せ:

WHERE 1=1 
    AND DECODE(a1.prev_start_date, NULL, 'THIS IS NOT NULL', a1.prev_end_date) IS NOT NULL 

私は以下の行が表示されません。上記の構文を追加

、なぜ?

表:

ID  prev_start_date prev_end_date 
456  2/13/2017   

答えて

2

ここでは、そのコードスニペットが何をするかです:

prev_start_dateNULLの場合、関数は、文字列'THIS IS NOT NULL'を返します。その文字列はNULLではないため、条件はTRUEと評価されます。

prev_start_dateNULLその後、DECODE()リターンprev_end_dateされていない場合。 prev_end_dateNULLでない場合にのみTRUEになります。

SO:条件はあなたが与えた例では、

明らか
(prev_start_date is null or prev_end_date is not null) 

に相当し、prev_start_dateNULLではありませんが、prev_end_dateNULLある - フィルタを通過しない値の正確組み合わせ。

0

日付有効性を有するレコード

レコード(例えば開始及び終了日)日付有効性を有している場合、通常、規則は終了日がNVL関数呼び出しを有するbetween条件を使用することです。

多くの発効日が終了していないという原則です。

示された開始日の前後にあるNULLのチェックは、条件(a NULLは除外されます)の間にこれで満足します。他の開始日がNULLである場合、 'これはNULLではありません'

」、:あなたが表示さDECODE文に関しては

、それは

WHERE 1=1 
    AND DECODE(a1.prev_start_date, NULL, 'THIS IS NOT NULL', a1.prev_end_date) IS NOT NULL 

DECODE文のように読むことができますprev_end_date "とは意味がありません。

次のように私は条件間でなければなりません:

[email protected]>WITH test AS 
    2 (SELECT hiredate prev_start_date, sysdate prev_end_date FROM emp 
    3 UNION ALL 
    4 SELECT to_date(NULL,'dd-mon-yyyy'), to_date(NULL,'dd-mon-yyyy') FROM dual 
    5 ) 
    6 SELECT prev_start_date, 
    7 prev_end_date 
    8 FROM test t 
    9 WHERE 1=1 
10 AND sysdate between t.prev_start_date and NVL(t.prev_end_date, sysdate); 
PREV_START_DATE   PREV_END_DATE    
17-DEC-1980 12:00:00 AM 27-SEP-2017 12:40:41 PM 
20-FEB-1981 12:00:00 AM 27-SEP-2017 12:40:41 PM 
22-FEB-1981 12:00:00 AM 27-SEP-2017 12:40:41 PM 
02-APR-1981 12:00:00 AM 27-SEP-2017 12:40:41 PM 
28-SEP-1981 12:00:00 AM 27-SEP-2017 12:40:41 PM 
01-MAY-1981 12:00:00 AM 27-SEP-2017 12:40:41 PM 
09-JUN-1981 12:00:00 AM 27-SEP-2017 12:40:41 PM 
09-DEC-1982 12:00:00 AM 27-SEP-2017 12:40:41 PM 
17-NOV-1981 12:00:00 AM 27-SEP-2017 12:40:41 PM 
08-SEP-1981 12:00:00 AM 27-SEP-2017 12:40:41 PM 
12-JAN-1983 12:00:00 AM 27-SEP-2017 12:40:41 PM 
03-DEC-1981 12:00:00 AM 27-SEP-2017 12:40:41 PM 
03-DEC-1981 12:00:00 AM 27-SEP-2017 12:40:41 PM 
23-JAN-1982 12:00:00 AM 27-SEP-2017 12:40:41 PM 


14 rows selected. 

NULLが結果セットから除外されます。

+0

oracle日付で 'between'を使用すると、oracle日付に時間が含まれているため、しばしば悪い考えです。 –

+0

あなたはそのアイディアをどこで手に入れましたか? 'start_date'と' end_date'では、 'between'演算子で条件を使うのが慣例ですか?これは真実ではありません(あなたがそのような大会を見た場所を教えてください)。多くの場合、不正確な結果につながる可能性があります。コンベンションでは 'start_date'はその行に関連する時間間隔に含まれますが、' end_date'は** excluded **です。一般的な規約は、 'dt> = start_dateとdt mathguy

+0

@mathguyこれはOracleアプリケーションコードに広がっています。 –