Oracle - Get all days from month - sql

How create select which return all days from month where month = PARAMETER_MONTH eg. 5 and year = extract(year from sysdate).
1
2
3
..
30
31

"Row generator" is the search keyword. For example:
SQL> with temp (col) as
2 (select to_date(&par_month, 'mm') from dual)
3 select to_number(to_char(col + level - 1, 'dd')) day
4 from temp
5 connect by level <= last_day(col) - col + 1
6 order by day;
Enter value for par_month: 5
DAY
----------
1
2
3
4
5
6
<snip>
29
30
31
31 rows selected.
SQL>
TO_DATE function will convert entered value into the 1st day of that month in current year, so you don't have to worry about "and year = extract(year from sysdate)" you mentioned in question.

Related

Calculate manual week number of year in Oracle SQL

i have a date column and along that i need to calculate another column in oracle for week number of they year, the weeks should be from sunday to saturday, starting first day of the year.
for example for current year
Week 1 : 1 Jan 2020 (Wednesday) - 4 Jan 2020(Saturday)
Week 2 : 5 Jan 2020 (Sunday) - 11 Jan 2020(Saturday)
. . . . .
Week 5 : 26 Jan 2020 (Sunday) - 1 Feb 2020 (Saturday)
and so on...
You need to write your own logic using a hierarchy query.
Something like the following:
SQL> SELECT WEEKNUMBER,
2 WEEK_START,
3 CASE WHEN WEEKNUMBER = 1 THEN FIRST_WEEKEND ELSE WEEK_START + 6 END AS WEEK_END
4 FROM
5 (SELECT
6 CASE
7 WHEN LEVEL = 1 THEN FIRST_DAY
8 ELSE FIRST_WEEKEND + ( LEVEL - 2 ) * 7 + 1
9 END AS WEEK_START,
10 FIRST_WEEKEND,
11 LEVEL AS WEEKNUMBER
12 FROM
13 ( SELECT
14 TRUNC(SYSDATE, 'YEAR') FIRST_DAY,
15 NEXT_DAY(TRUNC(SYSDATE, 'YEAR'), 'SATURDAY') FIRST_WEEKEND
16 FROM DUAL )
17 CONNECT BY
18 CASE WHEN LEVEL = 1 THEN FIRST_DAY
19 ELSE FIRST_WEEKEND + ( LEVEL - 2 ) * 7 + 1
20 END < ADD_MONTHS(TRUNC(SYSDATE, 'YEAR'), 12));
WEEKNUMBER WEEK_STAR WEEK_END
---------- --------- ---------
1 01-JAN-20 04-JAN-20
2 05-JAN-20 11-JAN-20
3 12-JAN-20 18-JAN-20
4 19-JAN-20 25-JAN-20
5 26-JAN-20 01-FEB-20
6 02-FEB-20 08-FEB-20
7 09-FEB-20 15-FEB-20
8 16-FEB-20 22-FEB-20
9 23-FEB-20 29-FEB-20
10 01-MAR-20 07-MAR-20
11 08-MAR-20 14-MAR-20
.......
.......
53 27-DEC-20 02-JAN-21
Cheers!!
One other option would be
with t as
(
select trunc(sysdate,'yyyy')+level-1 as day, to_char(trunc(sysdate,'yyyy')+level-1,'DY','NLS_DATE_LANGUAGE=AMERICAN') as weekday, level - 1 as lvl
from dual
connect by level <= 366
), t1 as
(
select case
when lvl = 0 then
day
else
case
when weekday = 'SUN' then
day
end
end as day1,
lvl
from t
), t2 as
(
select case
when weekday = 'SAT' then
day
end as day2,
lvl
from t
)
select concat( 'Week ', wk1) as week, day1, day2
from
(
select row_number() over (order by lvl) wk1, day1
from t1 where day1 is not null ) t1
left join
(
select row_number() over (order by lvl) wk2, day2
from t2 where day2 is not null ) t2
on wk2 = wk1
by using select .. from dual connect by level syntax and case..when expression to scan all the current year.
Demo

Counting the number of days excluding sunday between two dates

I am trying to calculate number of days betwen two dates excluding sundays. This is my query,
SELECT F_PLANHM_END_DT
- F_PLANHM_ST_DT
- 2
* (TO_CHAR (F_PLANHM_END_DT, 'WW') - TO_CHAR (F_PLANHM_ST_DT, 'WW'))
FROM VW_S_CURV_PROC
WHERE HEAD_MARK = 'IGG-BLH-BM 221';
SELECT COUNT (*)
FROM (SELECT SYSDATE + l trans_date
FROM ( SELECT LEVEL - 1 l
FROM VW_S_CURV_PROC
CONNECT BY LEVEL <= ( (SYSDATE + 7) - SYSDATE)))
WHERE TO_CHAR (trans_date, 'dy') NOT IN ('sun');
I am retrieving date from a view called VW_S_CURV_PROC with start date : F_PLANHM_ST_DT and end date F_PLANHM_END_DT. Somehow i cant make this to work. Please help me...
You could use the ROW GENERATOR technique to first generate the dates for a given range, and then exclude the SUNDAYs.
For example, this query will give me the total count of days between 1st Jan 2014 and 31st Dec 2014, excluding the Sundays -
SQL> WITH DATA AS
2 (SELECT to_date('01/01/2014', 'DD/MM/YYYY') date1,
3 to_date('31/12/2014', 'DD/MM/YYYY') date2
4 FROM dual
5 )
6 SELECT SUM(holiday) holiday_count
7 FROM
8 (SELECT
9 CASE
10 WHEN TO_CHAR(date1+LEVEL-1, 'DY','NLS_DATE_LANGUAGE=AMERICAN') <> 'SUN'
11 THEN 1
12 ELSE 0
13 END holiday
14 FROM data
15 CONNECT BY LEVEL <= date2-date1+1
16 )
17 /
HOLIDAY_COUNT
-------------
313
SQL>

oracle select data between date range using connect by clause

I have data something like this
date count
01-JAN-2015 10
02-JAN-2015 20
03-JAN-2015 30
01-FEB-2015 4
02-FEB-2015 8
03-FEB-2015 12
01-MAR-2015 5
02-MAR-2015 10
03-MAR-2015 15
01-APR-2015 6
02-APR-2015 12
03-APR-2015 18
01-MAY-2015 7
02-MAY-2015 14
03-MAY-2015 21
01-JUN-2015 8
02-JUN-2015 16
03-JUN-2015 24
01-JUL-2015 8
02-JUL-2015 16
03-JUL-2015 24
I need result group by months with variable number of months from current month
Example If I need only for next 2 months from today result is
MAR-2015 24
APR-2015 36
and If I need only for next 3 months from today result is
MAR-2015 24
APR-2015 36
MAY-2015 42
I have query to the get variable months with start date and end date of month
SELECT TO_CHAR(TRUNC(ADD_MONTHS(sysdate,level),'MM'),'MON-yyyy') MNTH ,
TO_CHAR(TRUNC(ADD_MONTHS(sysdate,level),'MM'),'dd-MON-yyyy') strt_date,
TO_CHAR(TRUNC(LAST_DAY(ADD_MONTHS(SYSDATE, level))),'dd-MON-yyyy') end_date
FROM dual
CONNECT BY LEVEL <= p_level
Where p_level is variable number of months like 2,3,4....
Can any 1 help using SQL query without using PL/SQL
You don't need to use a connect by clause at all.
select to_char(trunc(t.date, 'mm'), 'MON-YY')
, count(1)
from your_table_here t
where trunc(t.date, 'mm') > sysdate
and trunc(t.date, 'mm') < add_months(sysdate, :months)
group by trunc(t.date, 'mm')
Just insert the correct value for :months variable.

extracting total days of a month and then use it to get average sales per day

Hi i've been working on this project and need to get this.
SELECT sf.ORDER_QNT, dd.ACTUAL_DATE, dd.MONTH_NUMBER
FROM sales_fact sf,
date_dim dd
WHERE dd.date_id = sf.date_id
AND dd.MONTH_NUMBER = 1;
the result is the following:
ORDER_QNT ACTUAL_DATE MONTH_NUMBER
---------- ----------- ------------
1100 05/01/13 1
100 05/01/13 1
140 06/01/13 1
110 07/01/13 1
200 08/01/13 1
500 08/01/13 1
230 08/01/13 1
500 08/01/13 1
200 08/01/13 1
53 15/01/13 1
53 22/01/13 1
Now, I want to get the average for that month (average per day).
SELECT sum(sf.ORDER_QNT)/31 as AVGPERDAY
FROM sales_fact sf,
date_dim dd
WHERE dd.date_id = sf.date_id
AND dd.MONTH_NUMBER = 1;
The question is, instead of putting 31, how can I get the total day of the month? and how can I apply that to the SELECT query. I'm pretty good with logic(c++), but this database is pretty new to me. I'm using Oracle 11g by the way. Thank you for any help.
The question is, instead of putting 31, how can I get the total day of the month?
Pick any one solution :
1.
You can add a month to a date and substract both the dates :
ADD_MONTHS(date_col, 1) - date_col
Example :
SQL> WITH dates AS(
2 SELECT to_date('05/01/13','mm/dd/rr') dt FROM dual UNION ALL
3 SELECT to_date('06/01/13','mm/dd/rr') dt FROM dual UNION ALL
4 SELECT to_date('02/01/13','mm/dd/rr') dt FROM dual)
5 SELECT ADD_MONTHS(dt, 1) - dt num_of_days_per_month
6 from dates
7 /
NUM_OF_DAYS_PER_MONTH
---------------------
31
30
28
Or,
You can extract the last day of the month :
EXTRACT(DAY FROM LAST_DAY (date_col))
Example :
SQL> WITH dates AS(
2 SELECT to_date('05/01/13','mm/dd/rr') dt FROM dual UNION ALL
3 SELECT to_date('06/01/13','mm/dd/rr') dt FROM dual UNION ALL
4 SELECT to_date('02/01/13','mm/dd/rr') dt FROM dual)
5 SELECT EXTRACT(DAY FROM LAST_DAY(dt)) num_of_days_per_month
6 from dates
7 /
NUM_OF_DAYS_PER_MONTH
---------------------
31
30
28

Oracle sql sort week days by current day

I am trying to sort the days based on the order: Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday.
I am trying using case:
select day,
CASE day
WHEN 1 THEN 1
WHEN 2 THEN 2
WHEN 3 THEN 3
WHEN 4 THEN 4
WHEN 5 THEN 5
WHEN 6 THEN 6
WHEN 7 THEN 7
else 0
END as day_nr
from week where day in (1,2,3,4,5,6,7)
order by day_nr asc
This is ok when I select all the days of the week. But if I want only for the day 1,5,6 the ordering is not correct. Gets the first day -Monday. How to proceed?
If you're trying to sort a set of dates by day of the week, with Saturday being the first, then consider ordering by a modified date:
create table t1(my_date date);
insert into t1
select trunc(sysdate)+rownum
from dual
connect by level <= 20
select
my_date,
to_char(my_date,'Day'),
to_char(my_date,'D')
from
t1
order by
to_char(my_date + 1,'D');
http://sqlfiddle.com/#!4/5940b/3
The downside is that it's not very intuitive, so add a code comment if you use this method.
Edit: Where you have a list of numbers, order by a case statement with either a list conversion:
case day
when 1 then 3
when 2 then 4
when 3 then 5
when 4 then 6
when 5 then 7
when 6 then 1 -- saturday
when 7 then 2
end
... or the more compact, but not as intuitive:
case
when day <= 5 then day + 2
else day - 5
end
order by case
In Oracle day 1 is Sunday by default.
SELECT * FROM
(
SELECT trunc(sysdate) + LEVEL-1 my_dt
, TO_CHAR(trunc(sysdate) + LEVEL-1, 'DY') Wk_Day
, TO_CHAR(trunc(sysdate) + LEVEL-2, 'D' ) Day#
FROM dual
CONNECT BY LEVEL <= 10
)
WHERE Day# IN (1,5,6)
ORDER BY my_dt, Day#
/
MY_DT WK_DAY DAY#
------------------------
5/10/2013 FRI 5
5/11/2013 SAT 6
5/13/2013 MON 1
5/17/2013 FRI 5
5/18/2013 SAT 6