Home » SQL & PL/SQL » SQL & PL/SQL » How to count working day
How to count working day [message #623023] Wed, 03 September 2014 07:24 Go to next message
aaditya321
Messages: 225
Registered: January 2014
Location: Delhi
Senior Member
Hi Guys,

I have to count working days of September 2014 except Saturday & Sunday. Please help me how to count working days using PL/sql function.

[Updated on: Wed, 03 September 2014 07:26]

Report message to a moderator

Re: How to count working day [message #623025 is a reply to message #623023] Wed, 03 September 2014 07:34 Go to previous messageGo to next message
Littlefoot
Messages: 21808
Registered: June 2005
Location: Croatia, Europe
Senior Member
Account Moderator
Just like you said it: you need the whole year (use row generator to create it) and count days that aren't saturdays nor sundays. For example:
SQL> WITH the_whole_year
  2          AS (    SELECT TRUNC (SYSDATE, 'yyyy') + LEVEL - 1 datum
  3                    FROM DUAL
  4              CONNECT BY LEVEL <=
  5                            ADD_MONTHS (TRUNC (SYSDATE, 'yyyy'), 12)
  6                            - TRUNC (SYSDATE, 'yyyy'))
  7  SELECT COUNT (*)
  8    FROM the_whole_year
  9   WHERE TRIM (TO_CHAR (datum, 'day', 'nls_date_language = english')) NOT IN
 10            ('saturday', 'sunday');

  COUNT(*)
----------
       261

SQL>
Re: How to count working day [message #623027 is a reply to message #623025] Wed, 03 September 2014 08:32 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Brute force. Wink

(By the way, for only September 2014, trunc should be on MONTH and LAST_DAY gives the number of days in the month.)

Re: How to count working day [message #623029 is a reply to message #623023] Wed, 03 September 2014 08:46 Go to previous messageGo to next message
manubatham20
Messages: 566
Registered: September 2010
Location: Seattle, WA, USA
Senior Member

SELECT count(*)
  FROM (    SELECT TO_DATE (LEVEL || '-10-2014', 'DD-MM-YYYY') datum
              FROM DUAL
        CONNECT BY LEVEL <=
                      TO_NUMBER (
                         TO_CHAR (LAST_DAY (TO_DATE ('10-2014', 'MM-YYYY')),
                                  'DD')))
 WHERE TRIM (TO_CHAR (datum, 'day', 'nls_date_language = english')) NOT IN
          ('saturday', 'sunday');


Manu
Re: How to count working day [message #623030 is a reply to message #623029] Wed, 03 September 2014 08:50 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
I see no addition to what LF already posted. In fact, your query is just a part of the_whole_year.
Re: How to count working day [message #623032 is a reply to message #623029] Wed, 03 September 2014 09:08 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3273
Registered: January 2010
Location: Connecticut, USA
Senior Member
TO_DATE (LEVEL || '-10-2014', 'DD-MM-YYYY') is more writing and slower than DATE '2014-09-30' + LEVEL.

SY.
Re: How to count working day [message #623035 is a reply to message #623032] Wed, 03 September 2014 09:25 Go to previous messageGo to next message
manubatham20
Messages: 566
Registered: September 2010
Location: Seattle, WA, USA
Senior Member

Will it be slow, because I have written code using more characters, and more bytes are being sent, or is there any other reason?

SQL> SET AUTOTRACE ON
SQL> SELECT TO_DATE (1 || '-10-2014', 'DD-MM-YYYY') FROM DUAL;

TO_DATE(1
---------
01-OCT-14


Execution Plan
----------------------------------------------------------
Plan hash value: 1546270724

-------------------------------------------------
| Id  | Operation        | Name | Rows  | Cost  |
-------------------------------------------------
|   0 | SELECT STATEMENT |      |     1 |     2 |
|   1 |  FAST DUAL       |      |     1 |     2 |
-------------------------------------------------

Note
-----
   - cpu costing is off (consider enabling it)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          0  consistent gets
          0  physical reads
          0  redo size
        558  bytes sent via SQL*Net to client
        525  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> SELECT DATE '2014-09-30' + 1 FROM DUAL;

DATE'2014
---------
01-OCT-14


Execution Plan
----------------------------------------------------------
Plan hash value: 1546270724

-------------------------------------------------
| Id  | Operation        | Name | Rows  | Cost  |
-------------------------------------------------
|   0 | SELECT STATEMENT |      |     1 |     2 |
|   1 |  FAST DUAL       |      |     1 |     2 |
-------------------------------------------------

Note
-----
   - cpu costing is off (consider enabling it)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          0  consistent gets
          0  physical reads
          0  redo size
        541  bytes sent via SQL*Net to client
        525  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL>


Manu
Re: How to count working day [message #623041 is a reply to message #623035] Wed, 03 September 2014 10:22 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Very useful trace to compute consumptions on a single expression!

Re: How to count working day [message #623043 is a reply to message #623041] Wed, 03 September 2014 10:46 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
Manu,

CPU cost would tell more about the resource usage and overhead. Would you, please, show the CPU costing.
Re: How to count working day [message #623045 is a reply to message #623035] Wed, 03 September 2014 11:44 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3273
Registered: January 2010
Location: Connecticut, USA
Senior Member
TO_DATE (LEVEL || '-10-2014', 'DD-MM-YYYY') does:

a) concatenation
b) conversion

DATE '2014-09-30' + LEVEL

does just date arithmetic which in Oracle is built-in functionality.

SQL> DECLARE
  2      CURSOR v_cur
  3        IS
  4          SELECT  TO_DATE(LEVEL || '-10-2014','DD-MM-YYYY') DT
  5            FROM  DUAL
  6            CONNECT BY LEVEL <= 31;
  7      v_dt DATE;
  8  BEGIN
  9      FOR v_i IN 1..1000000 LOOP
 10        FOR v_rec IN v_cur LOOP
 11          v_dt := v_rec.dt;
 12      END LOOP;
 13      END LOOP;
 14  END;
 15  /

PL/SQL procedure successfully completed.

Elapsed: 00:01:52.97
SQL> DECLARE
  2      CURSOR v_cur
  3        IS
  4          SELECT  DATE '2014-09-30' + LEVEL DT
  5            FROM  DUAL
  6            CONNECT BY LEVEL <= 31;
  7      v_dt DATE;
  8  BEGIN
  9      FOR v_i IN 1..1000000 LOOP
 10        FOR v_rec IN v_cur LOOP
 11          v_dt := v_rec.dt;
 12      END LOOP;
 13      END LOOP;
 14  END;
 15  /

PL/SQL procedure successfully completed.

Elapsed: 00:01:23.77
SQL> 


SY.
Re: How to count working day [message #623048 is a reply to message #623027] Wed, 03 September 2014 12:14 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3273
Registered: January 2010
Location: Connecticut, USA
Senior Member
Michel Cadot wrote on Wed, 03 September 2014 09:32

Brute force. Wink


OK, math based solution:

select  to_char(dt,'fmMonth, yyyy') dt,
        trunc((last_day(dt) - trunc(dt,'iw') + 1) / 7) * 5 +
          least(mod(last_day(dt) - trunc(dt,'iw') + 1,7),5) - least(dt - trunc(dt,'iw'),5) work_days
  from  t
/


For example:

with t as (
           select  add_months(to_date('01/01/&year','mm/dd/yyyy'),level - 1) dt
             from  dual
             connect by level <= 12
          )
select  to_char(dt,'fmMonth, yyyy') dt,
        trunc((last_day(dt) - trunc(dt,'iw') + 1) / 7) * 5 +
          least(mod(last_day(dt) - trunc(dt,'iw') + 1,7),5) - least(dt - trunc(dt,'iw'),5) work_days
  from  t
/
Enter value for year: 2014
old   2:            select  add_months(to_date('01/01/&year','mm/dd/yyyy'),level - 1) dt
new   2:            select  add_months(to_date('01/01/2014','mm/dd/yyyy'),level - 1) dt

DT               WORK_DAYS
--------------- ----------
January, 2014           23
February, 2014          20
March, 2014             21
April, 2014             22
May, 2014               22
June, 2014              21
July, 2014              23
August, 2014            21
September, 2014         22
October, 2014           23
November, 2014          20

DT               WORK_DAYS
--------------- ----------
December, 2014          23

12 rows selected.

SQL> 


And speed comparison:

SQL> DECLARE
  2      CURSOR v_cur
  3        IS
  4  with t as (
  5             select  add_months(to_date('01/01/2014','mm/dd/yyyy'),level - 1) dt
  6               from  dual
  7               connect by level <= 12
  8            )
  9  select  to_char(trunc(dt,'mm'),'fmMonth, yyyy') dt,
 10          count(*) work_days
 11    from  (
 12           select  dt + level - 1 dt
 13             from  t
 14             connect by dt = prior dt
 15                    and prior sys_guid() is not null
 16                    and dt + level - 1 <= last_day(dt)
 17          ) a
 18    where to_char(dt,'fmday','nls_date_language = english') not in ('saturday','sunday')
 19    group by trunc(dt,'mm');
 20      v_work_days NUMBER;
 21  BEGIN
 22      FOR v_i IN 1..10000 LOOP
 23        FOR v_rec IN v_cur LOOP
 24          v_work_days := v_rec.work_days;
 25      END LOOP;
 26      END LOOP;
 27  END;
 28  /

PL/SQL procedure successfully completed.

Elapsed: 00:02:21.88
SQL> DECLARE
  2      CURSOR v_cur
  3        IS
  4  with t as (
  5             select  add_months(to_date('01/01/2014','mm/dd/yyyy'),level - 1) dt
  6               from  dual
  7               connect by level <= 12
  8            )
  9  select  to_char(dt,'fmMonth, yyyy') dt,
 10          trunc((last_day(dt) - trunc(dt,'iw') + 1) / 7) * 5 +
 11            least(mod(last_day(dt) - trunc(dt,'iw') + 1,7),5) - least(dt - trunc(dt,'iw'),5) work_days
 12    from  t;
 13      v_work_days NUMBER;
 14  BEGIN
 15      FOR v_i IN 1..10000 LOOP
 16        FOR v_rec IN v_cur LOOP
 17          v_work_days := v_rec.work_days;
 18      END LOOP;
 19      END LOOP;
 20  END;
 21  /

PL/SQL procedure successfully completed.

Elapsed: 00:00:01.07
SQL> 


SY.
Re: How to count working day [message #623074 is a reply to message #623048] Thu, 04 September 2014 01:40 Go to previous messageGo to next message
aaditya321
Messages: 225
Registered: January 2014
Location: Delhi
Senior Member
Thank you to all guys for supporting us.
Re: How to count working day [message #631201 is a reply to message #623074] Sat, 10 January 2015 05:33 Go to previous messageGo to next message
shahzad-ul-hasan
Messages: 615
Registered: August 2002
Senior Member
count the no of Sundays fall in specific date of the month.show sundays date.???
Re: How to count working day [message #631205 is a reply to message #631201] Sat, 10 January 2015 05:49 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
Sorry, but couldn't understand your question properly. Are you asking how to check if the date is Sunday? Then you could do -

to_char(sysdate, 'DY') = 'SUN'


If you want to check for all the dates in a month or whole year, then use ROW GENERATOR to check.

If this is not the question, then please elaborate.

[Updated on: Sat, 10 January 2015 05:51]

Report message to a moderator

Re: How to count working day [message #631207 is a reply to message #631205] Sat, 10 January 2015 05:52 Go to previous messageGo to next message
shahzad-ul-hasan
Messages: 615
Registered: August 2002
Senior Member
for example. if sunday fall on 04-jan-2015 then on reports how i can assign/show (Sunday) to filed on 04-jan-2015.
Quote:

1-Jan-15 P
2-Jan-15 A
3-Jan-15 A
4-Jan-15 Sunday
5-Jan-15 P
6-Jan-15 P
7-Jan-15 P
8-Jan-15 P
9-Jan-15 L
10-Jan-15 P
11-Jan-15 Sunday

[Updated on: Sat, 10 January 2015 05:55]

Report message to a moderator

Re: How to count working day [message #631208 is a reply to message #631207] Sat, 10 January 2015 05:56 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
Use the same TO_CHAR. DY format model gives the abbreviated form of the days, DAY gives full name, but blank padded. Use whatever is appropriate for you.

Ok, I see you have edited your post.

You could do -

DECODE(to_char(dt_col, 'DY'), 'SUN', to_char(dt_col, 'DD-MM-YYYY')||' SUNDAY', to_char(dt_col, 'DD-MM-YYYY'))


You could also do it using CASE expression.

[Updated on: Sat, 10 January 2015 06:01]

Report message to a moderator

Re: How to count working day [message #631213 is a reply to message #631208] Sat, 10 January 2015 07:46 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3273
Registered: January 2010
Location: Connecticut, USA
Senior Member
All that you posted is NLS dependent:

SQL> select to_char(sysdate,'DY') from dual; -- NLS dependent

TO_
---
SAT

SQL> alter session set nls_language=spanish;

Session altered.

SQL> select to_char(sysdate,'DY') from dual; -- NLS dependent

TO_
---
SAB

SQL> alter session set nls_language=swedish;

Session altered.

SQL> select to_char(sysdate,'DY') from dual; -- NLS dependent

TO
--
LO

SQL> select to_char(sysdate,'DY','nls_date_language=english') from dual; -- NLS independent

TO_
---
SAT

SQL>  


SY.
Re: How to count working day [message #631219 is a reply to message #631213] Sat, 10 January 2015 09:17 Go to previous message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
Thanks, I missed it.

DECODE(to_char(dt_col, 'DY','nls_date_language = english'), 'SUN', to_char(dt_col, 'DD-MM-YYYY')||' SUNDAY', to_char(dt_col, 'DD-MM-YYYY'))

Previous Topic: how to run PLSQL procedure in foreground in SQL command prompt
Next Topic: LOB
Goto Forum:
  


Current Time: Thu Apr 25 00:16:47 CDT 2024