Получить счетчик текущих дней за текущий месяц, кроме выходных - PullRequest
0 голосов
/ 05 декабря 2018

Я новичок в SQL.Я должен получить текущий счетчик дней (Day Number) из текущего системного месяца, который не должен учитывать выходные (суббота и воскресенье).

Например, если я выполняю запрос сегодня (05 декабря 2018 года), тогда мой вывод должен быть 3 (текущая дата 05-12-2018, здесь 1 декабря - суббота, а 2 декабря - воскресенье. IЯ не хочу включать выходные в этот расчет, поэтому понедельник (3 декабря) будет 1, вторник (4 декабря) будет 2, а среда (5 декабря) будет 3.

Любая помощь для этоговысоко ценится.

Ответы [ 4 ]

0 голосов
/ 05 декабря 2018

Вам не нужно использовать иерархический запрос, и вы можете выполнять его независимо от настроек NLS, используя TRUNC( date_value, 'IW' ), чтобы найти начало недели ISO, которая всегда является понедельником.

Итак:

TRUNC( SYSDATE, 'IW' ) - TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' )

Найдет количество дней между началом недели ISO, содержащей первый день месяца, и началом текущей недели ISO.Умножив это на 5/7, мы получим количество дней недели.

Затем вам нужно будет узнать, сколько из этих дней произошло в предыдущем месяце, и вычесть их.Это можно найти, используя:

LEAST( TRUNC( SYSDATE, 'MM' ) - TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' ), 5 )

и сколько дней нужно добавить для текущей недели;который задается следующим образом:

LEAST( TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ) + 1, 5 )

Таким образом, общее количество можно найти с помощью:

SELECT ( TRUNC( SYSDATE, 'IW' ) - TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' ) ) * 5 / 7
       + LEAST( TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ) + 1, 5 )
       - LEAST( TRUNC( SYSDATE, 'MM' ) - TRUNC( TRUNC( SYSDATE, 'MM' ), 'IW' ), 5 )
         AS Num_Week_Days
FROM  DUAL;

Пример с несколькими днями:

WITH calendar ( date_value ) AS (
  SELECT DATE '2018-12-01' + LEVEL - 1
  FROM   DUAL
  CONNECT BY LEVEL <= 15
)
SELECT date_value,
       TO_CHAR( date_value, 'DY' ) AS day,
       ( TRUNC( date_value, 'IW' ) - TRUNC( TRUNC( date_value, 'MM' ), 'IW' ) ) * 5 / 7
       + LEAST( TRUNC( date_value ) - TRUNC( date_value, 'IW' ) + 1, 5 )
       - LEAST( TRUNC( date_value, 'MM' ) - TRUNC( TRUNC( date_value, 'MM' ), 'IW' ), 5 )
         AS Num_Week_Days
FROM  Calendar;

Выходные данные:

DATE_VALUE  DAY NUM_WEEK_DAYS
----------  --- -------------
2018-12-01  SAT 0
2018-12-02  SUN 0
2018-12-03  MON 1
2018-12-04  TUE 2
2018-12-05  WED 3
2018-12-06  THU 4
2018-12-07  FRI 5
2018-12-08  SAT 5
2018-12-09  SUN 5
2018-12-10  MON 6
2018-12-11  TUE 7
2018-12-12  WED 8
2018-12-13  THU 9
2018-12-14  FRI 10
2018-12-15  SAT 10
0 голосов
/ 05 декабря 2018

Этот тип запроса действительно легко написать, если вы поддерживаете таблицу calendar в своей базе данных.Вот запрос, который генерирует частичный календарь всех дней от начала месяца до сегодняшнего дня.Тогда мы можем посчитать количество будних дней.

select count(*)
  from (select trunc(sysdate, 'MM') - 1 + level as d
          from dual 
       connect by level <= trunc(sysdate, 'DD') + 1 -- Today
                         - trunc(sysdate, 'MM')     -- First day of current month
       )
 -- Exclude weekends 
 where to_char(d, 'DY', 'nls_date_language=american') not in('SAT', 'SUN') 
 ;
0 голосов
/ 05 декабря 2018

Вы можете использовать этот оператор выбора sql с предложением connect by level:

 select sum(dy) "Total Day"
   from
   (
    select (case when to_char(sysdate-level+1,'D','nls_date_language=turkish') in (6,7)
                 then 0
                 else 1 end ) as dy
      from dual
   connect by level <= to_number(to_char(sysdate,'DD'))
   );

  Total Day
  ---------
      3

Вы можете попробовать другие случаи, заменив оба ключевых слова sysdate на sysdate + 3, sysdate + 4, sysdate + 5 ... и т. д.

0 голосов
/ 05 декабря 2018

Это должно работать для SQL Server

SET @today= '2018-12-14'

SET @firstDate = (SELECT DATEADD(month, DATEDIFF(month, 0, @today), 0) AS StartOfMonth);

WITH allDates AS 
(
    SELECT 
            @firstDate AS DT
    UNION ALL
            SELECT 
                DATEADD(dd, 1, DT)
            FROM 
                allDates as S 
            WHERE 
                DATEADD(dd, 1, DT) <= @today
)
SELECT  count(*)  FROM allDates  where  DATENAME(dw,DT) <> 'Saturday' and DATENAME(dw,DT) <> 'Sunday' option (maxrecursion 0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...