1

各月の日数を計算するために、この SQL ステートメントを作成しました

(select count(*) DAYs FROM
    (
     select trunc(ADD_MONTHS(sysdate,-1),'MM') +  level -1 Dates from dual connect by
      level <= ADD_MONTHS(trunc(sysdate,'MM'),1)-1 -  trunc(sysdate,'MM')+1
   ) Where To_char(dates,'DY') NOT IN ('SA','SO'))

現時点では、このステートメントは土曜日と日曜日を無視し、sysdate の前の月 (6 月) からの日数を計算します。

6 月には週末のない 22 日がありますが、悲しいことに、私の声明では 23 日と書かれています。7 月 1 日が含まれていることがわかりましたが、これは間違っています。

取得したい月からの日数のみを計算し、別の月からの日数を含まない私の小さなステートメントをどのように伝えることができるか知っていますか?

4

3 に答える 3

3

この種のことを行うと、常に見栄えが悪くなります...これは、今年全体でそれを行う1つの方法です. where 句に追加のステートメントを追加することで、1 か月に制限できます。

 select to_char(trunc(sysdate, 'y') + level - 1, 'fmMON') as month, count(*)
   from dual
  where to_char(trunc(sysdate, 'y') + level - 1, 'fmDY', 'nls_date_language=english') not in ('SAT','SUN')
connect by level <= trunc(add_months(sysdate, 12), 'y') - trunc(sysdate, 'y')
  group by to_char(trunc(sysdate, 'y') + level - 1, 'fmMON')

私が言ったように、きれいではありません。

次の点に注意してください。

  • fmフォーマット モデル修飾子を使用して先頭のスペースを削除する
  • を明示的に使用しnls_date_languageて、すべての環境で確実に機能するようにします
  • 簡単にするために、現在の日付に 12 か月を加算し、1 月 1 日に切り捨てて新年の初日を取得しました。
  • これを月ごとに実行したい場合は、LAST_DAY()関数を見る価値があるかもしれません

LAST_DAY()前月のみの同じステートメント ( を使用) は次のようになります。

 select count(*)
   from dual
  where to_char(trunc(sysdate, 'y') + level - 1, 'fmDY', 'nls_date_language=english') not in ('SAT','SUN')
connect by level <= last_day(add_months(trunc(sysdate, 'mm'), -1)) - add_months(trunc(sysdate, 'mm'), -1) + 1
于 2015-07-28T07:48:44.867 に答える
2

まず、内部クエリ ( select trunc(ADD_MONTHS(sysdate,-1),'MM') + level -1 Dates from dual connect by level <= ADD_MONTHS(trunc(sysdate,'MM'),1)-1 - trunc(sysdate,'MM')+1) は、その月の日数に加えて、翌月から 1 日を追加して返します。

第 2 に、より単純なクエリでは、月の最終日を取得する LAST_DAY 関数を使用できます。

最後に、'D'日付形式を使用して曜日を数値として取得します。

SELECT COUNT(*) FROM (
  SELECT TO_CHAR(TRUNC(SYSDATE,'MM') + ROWNUM - 1, 'D') d
  FROM dual CONNECT BY LEVEL <= TO_NUMBER(TO_CHAR(LAST_DAY(SYSDATE),'DD'))
) WHERE d BETWEEN 1 AND 5;
于 2015-07-28T07:52:57.957 に答える
1

月のすべての日を生成してからカウントする必要はありません。

SQL フィドル

Oracle 11g R2 スキーマのセットアップ:

CREATE FUNCTION WORK_DAYS_IN_MONTH(
  dt DATE
) RETURN NUMBER DETERMINISTIC
AS
  first_day DATE   := TRUNC( dt, 'MM' );
  remainder NUMBER := LAST_DAY( dt ) - ( first_day + INTERVAL '27' DAY );
BEGIN
  RETURN 20 + CASE first_day - TRUNC( first_day, 'IW' )
                   WHEN 0 THEN remainder                  -- Monday
                   WHEN 1 THEN remainder                  -- Tuesday
                   WHEN 2 THEN remainder                  -- Wednesday
                   WHEN 3 THEN LEAST( remainder, 2 )      -- Thursday
                   WHEN 4 THEN LEAST( remainder, 1 )      -- Friday
                   WHEN 5 THEN GREATEST( remainder-2, 0 ) -- Saturday
                          ELSE GREATEST( remainder-1, 0 ) -- Sunday
                   END;
END;
//

クエリ 1 :

SELECT ADD_MONTHS( DATE '2014-12-01', LEVEL ) AS "Month",
       WORK_DAYS_IN_MONTH( ADD_MONTHS( DATE '2014-12-01', LEVEL ) ) AS "# Work Days"
FROM   DUAL
CONNECT BY LEVEL <= 12

結果

|                       Month | # Work Days |
|-----------------------------|-------------|
|   January, 01 2015 00:00:00 |          22 |
|  February, 01 2015 00:00:00 |          20 |
|     March, 01 2015 00:00:00 |          22 |
|     April, 01 2015 00:00:00 |          22 |
|       May, 01 2015 00:00:00 |          21 |
|      June, 01 2015 00:00:00 |          22 |
|      July, 01 2015 00:00:00 |          23 |
|    August, 01 2015 00:00:00 |          21 |
| September, 01 2015 00:00:00 |          22 |
|   October, 01 2015 00:00:00 |          22 |
|  November, 01 2015 00:00:00 |          21 |
|  December, 01 2015 00:00:00 |          23 |
于 2015-07-28T08:54:48.457 に答える