2

従業員テーブルがあります。私はそのような方法ですべての従業員のデータを取得する必要があります。今日クエリを実行すると、前年の12月1日(現在の1年目、つまり2010年12月1日)から今日(4月21日)までに働いていたすべての従業員のデータを取得する必要があります。クエリの実行日が12月(今日の例は12月15日)の場合、クエリは現在の年の12月1日(2011年12月1日)から12月15日までのデータを取得する必要があります。

この場合、誰かがIFまたはCASEステートメントを書き留めるのを手伝ってもらえますか。私はifステートメントをどのように機能しないかを書きました。このIfまたはCaseステートメントをemployee_timestampの開始日として使用したいと思います。これはここで可能かどうか。

SELECT e.* 
  FROM EMPLOYEE e
 WHERE e.employee_timestamp > (SELECT TO_DATE(TO_CHAR(CONCAT('12-01-', EXTRACT(YEAR FROM SYSDATE)-1)),'MM/DD/YYYY') AS startdate 
                                 FROM DUAL)
   AND e.employee_timestamp < (SELECT SYSDATE FROM DUAL)

IF
((SELECT SYSDATE FROM DUAL)) > (select to_date(to_char(concat('11-30-', extract(YEAR FROM sysdate))),'MM/DD/YYYY') as Startdate From DUAL)
THEN (select to_date(to_char(concat('12-01-', extract(YEAR FROM sysdate))),'MM/DD/YYYY') as Startdate From DUAL)
ELSE
(select to_date(to_char(concat('12-01-', extract(YEAR FROM sysdate)-1)),'MM/DD/YYYY') as Startdate From DUAL)
END IF;
4

4 に答える 4

2

最初に、すべてを文字列に変換したり、文字列から変換したりせずに、日付操作の例をいくつか示します。

SELECT SYSDATE - INTERVAL '1' YEAR -- returns the previous year from current date
 , TRUNC( SYSDATE, 'MM') -- returns the first day of the current month
 , ADD_MONTHS( TRUNC( SYSDATE, 'YYYY'), 11) -- returns December of current year
 , ADD_MONTHS( TRUNC( SYSDATE - INTERVAL '1' YEAR, 'YYYY'), 11) -- returns first day of december previous year
 , DECODE( TRUNC(SYSDATE, 'MM')
                                      , ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), 11), TRUNC( SYSDATE, 'MM' )
                                      , ADD_MONTHS(TRUNC(SYSDATE, 'YYYY' ), 11) - INTERVAL '1' YEAR ) -- this implements your logic
  from dual

現在の月が2011年12月でない場合、最後のデコードは2010年12月1日を返します。2011年12月に実行すると、2011年12月1日が返されます。

これで、日付範囲の希望に応じて、次のステートメントを使用できます。

日付範囲が包括的である場合

SELECT e.*
  FROM EMPLOYEE  e
 WHERE e.employee_timestamp  BETWEEN DECODE( TRUNC(SYSDATE, 'MM')
                                          , ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), 11), TRUNC( SYSDATE, 'MM' )
                                          , ADD_MONTHS(TRUNC(SYSDATE, 'YYYY' ), 11) - INTERVAL '1' YEAR )
                            AND SYSDATE

日付範囲が指定したものとまったく同じである場合(排他的)

   SELECT e.*
  FROM EMPLOYEE  e
 WHERE e.employee_timestamp  > DECODE( TRUNC(SYSDATE, 'MM')
                                          , ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), 11), TRUNC( SYSDATE, 'MM' )
                                          , ADD_MONTHS(TRUNC(SYSDATE, 'YYYY' ), 11) - INTERVAL '1' YEAR )
   AND e.employee_timestamp  < SYSDATE

これがあなたの質問に答えることを願っています:)これを文書化することを忘れないでください、このようなコードは何年も後に分析するのが難しいです。

于 2011-04-22T07:47:13.690 に答える
1

ifステートメントがないと、クエリで使用する希望の開始日が得られます。

SELECT TRUNC( ADD_MONTHS( sysdate, MOD( TO_NUMBER( TO_CHAR(sysdate, 'MM') ), 12) * (-1) ), 'MONTH') 
FROM dual;

少なくとも要件を正しく理解していれば...

于 2011-04-22T07:30:10.573 に答える
1
Select * from employee where 
employee_timestamp between
case
when to_char(sysdate,'mm') = '12'  then
                   trunc(sysdate,'MM')
else add_months(trunc(sysdate,'year'),-1)
end
and sysdate
于 2011-04-22T07:58:45.313 に答える
0
SELECT e.* 
  FROM EMPLOYEE e
WHERE e.employee_timestamp > ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), 11) -
        INTERVAL CASE TO_CHAR(SYSDATE, 'MM') WHEN '12' THEN '0' ELSE '1' END YEAR
  AND e.employee_timestamp < SYSDATE

e.employee_timestamp >= ...ではなく、そうあるべきだと思われe.employee_timestamp > ...ますが、もちろん、もっとよく知っている必要があります。

于 2011-04-22T07:59:15.897 に答える