I am looking to filter my reports so they gather all the data to Friday.
I.e. today is the 12th and I would like my report to gather info from my date range 5th to the 11th. Then tomorrow on the 13th still get the data from the 5th to the 11th.
just a weekly report that comes out on a Friday.
I cant use date diff on the server it doesn't let me on this Oracle
I was using this where (date >= trunc(SYSDATE) - 7) but I cant seem to get it to do Friday.
I did a lot of reading and there is a post about levels....... and saw this script. It shows the Friday but I have no idea how to get it to filter on my date column.
WITH dates AS (SELECT TRUNC(SYSDATE, 'mm') + LEVEL -11 dt
FROM dual
CONNECT BY LEVEL <= 22)
SELECT dt,
to_char(dt, 'fmDay') day_of_dt,
TRUNC(dt + 3, 'iw') - 3 prev_fri_incl_today,
TRUNC(dt + 2, 'iw') - 3 prev_fri_not_incl_today
FROM dates;
If you want the values from Saturday of the previous week until Friday of the current week (which, if it is currently Monday-Friday will contain future dates) then:
SELECT *
FROM table_name
WHERE date_column >= TRUNC(SYSDATE, 'iw') - 2
AND date_column < TRUNC(SYSDATE, 'iw') + 5
If you want to include a full historic week (i.e. if it is current Monday-Friday then get last week's range):
SELECT *
FROM table_name
WHERE date_column >= TRUNC(SYSDATE - 5, 'iw') - 2
AND date_column < TRUNC(SYSDATE - 5, 'iw') + 5
fiddle
I have query in access db which looks like this:-
IIf(Weekday([HiredDate])=7,[HiredDate],[HiredDate]-Weekday([HiredDate])) AS TrainingStart,
Date()+6-Weekday(Date()) AS EndOfWeek,
DateDiff("ww",[TrainingStart],[EndOfWeek]) AS WeekNumber,
How do I write query with same logic in my oracle.
Here is what I have written and I do not think it is right.
SELECT Name, HiredDate,
(CASE WHEN (to_char(to_date(HiredDate), 'd') = 7) THEN HiredDate ELSE (HiredDate - to_char(to_date(HiredDate), 'd')) END) as TraingStart,
(CURRENT_DATE + (6 - to_char(to_date(CURRENT_DATE), 'd'))) as EndDate,
(To_Number(to_char(to_date((CURRENT_DATE + (6 - to_char(to_date(CURRENT_DATE), 'd')))),'WW')) - To_number(to_char(to_date((HiredDate - to_char(to_date(HiredDate), 'd'))),'WW')) +1) as WEEKNUMBER
FROM employee;
I always use something like following to count weeks as Change in the year of the start and end date can affect my result.
You can try the following:
WITH DATE_RANGE AS (
SELECT
DATE '2019-12-01' START_DATE,
DATE '2020-02-26' END_DATE
FROM
DUAL
)
SELECT
COUNT(LEVEL) AS NUMBER_OF_WEEKS
-- , LEVEL "Week",
-- TRUNC(START_DATE +(7 *(LEVEL - 1)), 'IW') AS START_OF_THE_WEEK,
-- TRUNC(START_DATE +(7 *(LEVEL - 1)), 'IW') + 6 AS END_OF_THE_WEEK,
-- TO_CHAR(START_DATE +(7 *(LEVEL - 1)), 'IW') WEEK_NUMBER
FROM
DATE_RANGE
CONNECT BY
LEVEL <= ( TRUNC(END_DATE, 'IW') - TRUNC(START_DATE, 'IW') ) / 7 + 1;
Output:
NUMBER_OF_WEEKS
---------------
14
Cheers!!
Try this to find number of weeks between 2 dates.
SELECT (trunc(TO_DATE(CURRENT_DATE, 'DD/MM/YYYY'), 'd')-trunc(TO_DATE(HIRED_DATE, 'DD/MM/YYYY'), 'd'))/7
FROM dual;
I'm trying to extract records from table inserted in last 5 working days on Oracle SQL
I'm unable to exclude Sunday and Saturday from this(as they're coming into consideration)
Select * from xyz where xdate=:businessDate - 5
Here businessDate (yyyymmdd format) is value taken as a parameter
Any pointers would greatly be valued and appreciated .
SELECT *
FROM xyz
WHERE
xdate >= TRUNC(SYSDATE) - 7 --last 7 days AND
TRUNC (xdate) - TRUNC (xdate, 'IW') NOT IN (5,6) --not sat or sun
Take the last 7 days data, and remove any data from saturday or sunday.
TRUNC (xdate) - TRUNC (xdate, 'IW') returns a value between 0 and 6 inclusive. 0 is monday. This is not affected by NLS date settings because it uses the same region setting in both truncs, so regardless if the week starts on sunday or monday in your country, the result of the calc is the same
In any given 7 day period you have 5 week days and 2 weekend days
Note that this query assumes the table has no future dated data. If it does put a restriction that xdate must be less than sysdate
I am not an oracle expert but this could also work
SELECT *
FROM xyz
WHERE xdate IN (:businessDate - 1, :businessDate - 2, :businessDate - 3, :businessDate - 4, :businessDate - 5, :businessDate - 6, :businessDate - 7) AND MOD(TO_CHAR(xdate, 'J'), 7) + 1 NOT IN (6, 7);
I would do:
select * from xyz
where xdate >= TO_DATE( :businessDate, 'yyyymmdd' ) - 7
and to_char( xdate, 'DAY' ) not in ( 'SAT', 'SUN' )
That's assuming you're working in an English database. That should give you the past 7 days worth, but exclude weekends.
You'll need to do something like the following:
WITH cteData AS (SELECT TO_DATE(:BUSINESSDATE, 'YYYYMMDD') AS BUSINESS_DATE FROM DUAL)
SELECT *
FROM XYZ x
CROSS JOIN cteData d
WHERE TRUNC(x.XDATE) BETWEEN d.BUSINESS_DATE - 7
AND d.BUSINESS_DATE AND
TRUNC(x.XDATE) - TRUNC(x.XDATE, 'IW') <= 4
Find out the weekend day i.e. Sunday or Saturday by using 'DAY' format in format_date function e.g.
IF FORMAT_DATE(Date,'DAY')='SATURDAY' then date-1
IF FORMAT_DATE(Date,'DAY')='SUNDAY' then date-2
You would get only 5 days record
If I write
select ename, to_char(hiredate,'fmDay') as "Day" order by "Day";
Then it sorts the result based on Day like; from Friday, then Monday and last Wednesday,
like sorting by characters.
But I want to sort it by day of the week; from Monday to Sunday.
You're getting it in the order you are because you're ordering by a string (and this wouldn't work because you're not selecting from anything).
You could order by the format model used to create the day of the week in numeric form, D, but as Sunday is 1 in this I would recommend using mod() to make this work.
i.e. assuming the table
create table a ( b date );
insert into a
select sysdate - level
from dual
connect by level <= 7;
This would work:
select mod(to_char(b, 'D') + 5, 7) as dd, to_char(b, 'DAY')
from a
order by mod(to_char(b, 'D') + 5, 7)
Here's a SQL Fiddle to demonstrate.
In your case your query would become:
select ename, to_char(hiredate,'fmDay') as "Day"
from my_table
order by mod(to_char(hiredate, 'D') + 5, 7)
SELECT
*
FROM
classes
ORDER BY
CASE
WHEN Day = 'Sunday' THEN 1
WHEN Day = 'Monday' THEN 2
WHEN Day = 'Tuesday' THEN 3
WHEN Day = 'Wednesday' THEN 4
WHEN Day = 'Thursday' THEN 5
WHEN Day = 'Friday' THEN 6
WHEN Day = 'Saturday' THEN 7
END ASC
Assuming that user has a table called classes in that table user has class_id (primary key), class name, Day.
Take a look at other formats for TO_CHAR. Instead of 'fmDay' use 'D' and it will give you the day of the week from 1 to 7. Then you can easily sort on it.
Here's a list of date formats: http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm
Why to complicate when you can add another column with numbers 1-7 corresponding to days and then sort by this column...
I just encountered the same requirement -- to order a query result by day of the week, but not starting with Sunday. I used the following query in Oracle to start w/ Monday. (Modify it to start the ordering w/ any day of the week, e.g., change 'MONDAY' to 'TUESDAY'.)
SELECT ename, to_char(hiredate, 'fmDAY') AS "Day"
FROM emp
ORDER BY (next_day(hiredate, 'MONDAY') - hiredate) DESC
Or:
SELECT ename, to_char(hiredate, 'fmDAY') AS "Day"
FROM emp
ORDER BY (hiredate - next_day(hiredate, 'MONDAY'))
The D format mask of to_char maps days of the week to the values 1-7.
But!
The output of this depends on the client's setting for NLS_TERRITORY. The US considers Sunday to be day 1. Whereas most of the rest of the world consider Monday to be the start:
alter session set nls_territory = AMERICA;
with dts as (
select date'2018-01-01' + level - 1 dt
from dual
connect by level <= 7
)
select to_char ( dt, 'Day' ) day_name,
to_char ( dt, 'd' ) day_number
from dts
order by day_number;
DAY_NAME DAY_NUMBER
Sunday 1
Monday 2
Tuesday 3
Wednesday 4
Thursday 5
Friday 6
Saturday 7
alter session set nls_territory = "UNITED KINGDOM";
with dts as (
select date'2018-01-01' + level - 1 dt
from dual
connect by level <= 7
)
select to_char ( dt, 'Day' ) day_name,
to_char ( dt, 'd' ) day_number
from dts
order by day_number;
DAY_NAME DAY_NUMBER
Monday 1
Tuesday 2
Wednesday 3
Thursday 4
Friday 5
Saturday 6
Sunday 7
Sadly, unlike many other NLS parameters, you can't pass NLS_TERRITORY as the third parameter of to_char:
with dts as (
select date'2018-01-01' dt
from dual
)
select to_char ( dt, 'Day', 'NLS_DATE_LANGUAGE = SPANISH' ) day_name
from dts;
DAY_NAME
Lunes
with dts as (
select date'2018-01-01' dt
from dual
)
select to_char ( dt, 'Day', 'NLS_TERRITORY = AMERICA' ) day_name
from dts;
ORA-12702: invalid NLS parameter string used in SQL function
So any solution relying on D for sorting is a bug!
To avoid this, subtract the most recent Monday from the date (if today is Monday, the most recent Monday = today). You can do this with the IW format mask. Which returns the start of the ISO week. Which is always a Monday:
with dts as (
select date'2018-01-01' + level - 1 dt
from dual
connect by level <= 7
)
select to_char ( dt, 'Day' ) day_name,
( dt - trunc ( dt, 'iw' ) ) day_number
from dts
order by day_number;
DAY_NAME DAY_NUMBER
Monday 0
Tuesday 1
Wednesday 2
Thursday 3
Friday 4
Saturday 5
Sunday 6
For Sunday-Saturday sorting, add one to the date before finding the start of the ISO week:
with dts as (
select date'2018-01-01' + level - 1 dt
from dual
connect by level <= 7
)
select to_char ( dt, 'Day' ) day_name,
( dt - trunc ( dt + 1, 'iw' ) ) day_number
from dts
order by day_number;
DAY_NAME DAY_NUMBER
Sunday -1
Monday 0
Tuesday 1
Wednesday 2
Thursday 3
Friday 4
Saturday 5
If you want Monday to be always treated as first day of week you could use:
-- Not affected by NLS_TERRITORY
-- ALTER SESSION SET NLS_TERRITORY="AMERICA"; -- Sunday is first day of week
-- ALTER SESSION SET NLS_TERRITORY="GERMANY"; -- Monday is first day of week
SELECT *
FROM tab
ORDER BY 1+TRUNC(dt)-TRUNC(dt,'IW');
db<>fiddle demo
It's simple.
SELECT last_name, hire_date,TO_CHAR(hire_date, 'DAY') DAY
FROM employees
ORDER BY TO_CHAR(hire_date - 1, 'd');
TO_CHAR(hire_date - 1, 'd') puts a 'Monday' into a box named 'Sunday'.
As it's said, there's a function for it:
SELECT *
FROM table
ORDER BY WEEKDAY(table.date);
Might be late to post the answer, But seems simple solution to sort by day of week starting from Monday.
select hiredate,dayname(hiredate) from emp order by (dayofweek(hiredate)+5)%7;
Answer for why added 5 ?
Because , In numbers Sunday has value 1, Monday has 2 ... and Saturday has 7
So, 2 + 5 = 7 and mod(%) with 7 will give us new values start from Monday.
You can change this number to start with any other day of week.
2nd option
simply use WEEKDAY() function return weekday number for a given date.
**Note:**
0 = monday
1 = tuesday
2 = wednesday
3 = thursday
4 = friday
5 = saturday
6 = sunday
select hiredate,dayname(hiredate) from emp order by WEEKDAY(hiredate);
I improved on Ben's answer by giving you a result which starts from 1 rather than 0. The query would be like this:
select
mod(to_char(b, 'D')+ 5, 7) +1 as dd,
to_char(b, 'DAY')
from a
order by mod(to_char(b, 'D')+ 5, 7);
On the other hand, if you want your week to start from Sunday, then you should use this query:
select
mod(to_char(b, 'D')+ 6, 7) +1 as dd,
to_char(b, 'DAY')
from a
order by mod(to_char(b, 'D')+ 6, 7)
Hope this helps :)
with s as (select trunc(sysdate) + level dt from dual connect by level <= 7)
select to_char(dt, 'fmDay', 'nls_date_language=English') d
from s
order by dt - trunc(dt, 'iw');
D
------------------------------------
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
7 rows selected.
I have some simple idea hope you like it. i don't which sql you are using so please correct syntax error.
select ename, to_char(hiredate,'fmDay') as "Day" from ABC_TABLE
JOIN (VALUES (1,'Monday'),(2,'Tuesday'),(3,'Wednesday'),(4,'Thursday'),(5,'Friday'),(6,'Saturday'),(7,'Sunday')) weekdays(seq,[Days]) on
ABC_TABLE.to_char(hiredate,'fmDay') = weekdays.[Days]
order by weekdays.seq;
I you want to start next week after end a week then just find quarter of month and add in order by clouse.
just for in of find Quarter in(MSSQL): select DatePart(QUARTER, cast(cast(mydate as char(8)) as date))
This should do the trick in sql:
ORDER BY
CASE DATENAME(dw,<<enter your date variable here>>)
WHEN 'Monday' THEN 1
WHEN 'Tuesday' THEN 2
WHEN 'Wednesday' THEN 3
WHEN 'Thursday' THEN 4
WHEN 'Friday' THEN 5
WHEN 'Saturday' THEN 6
WHEN 'Sunday' Then 7
END ASC;
Of course if you want different order you just switch the values after then.
For Postgres at least, to have Monday always be day 1, use TO_CHAR(b, 'ID') to return the ISO 8601 day of the week - Monday (1) to Sunday (7).
This is the International Standard's Organization (ISO) Day of the Week hence the I in front of the D in 'ID'.
https://www.postgresqltutorial.com/postgresql-to_char/
I think this is too late, but I will leave this here if anyone else needs it.
You can just order by day of the week, but it depends on the territory of your session.
In order to show the territory, you can simply execute this query:
SELECT * FROM V$NLS_PARAMETERS WHERE parameter = 'NLS_TERRITORY';
NLS_TERRITORY specifies the name of the territory whose conventions are to be followed for day and week numbering.
Back to the previous query, if you have AMERICA as the value, then Monday has the value 2.
To order your results from Monday to Sunday, you have at least 2 roads:
1- Decrease one day from hire_date:
SELECT * FROM employees ORDER BY TO_CHAR(hire_date - 1, 'd');
2- Alter the territory to a value that has 1 as the value of Monday, for example, FRANCE:
ALTER SESSION SET NLS_TERRITORY = 'FRANCE';
SELECT * FROM employees ORDER BY TO_CHAR(hire_date, 'd');
This is my solution.
select ename, to_char(hiredate,'fmDay') "Day"
from employees
order by DECODE(to_number(to_char(hiredate ,'D'))-1,
0, 7,
to_number(to_char(hiredate ,'D'))-1);
Basically converts day to a number by using 'D' format from to_char function.
to_number(to_char(hire_date ,'D')
But that causes Sunday to be 1 and Monday to be 2 and so on so I subtract 1 to make Monday 1.
(to_number(to_char(hire_date ,'D') - 1
Then I use DECODE function to basically say if 0, then 7, else original number. That just makes Sunday be 7 instead of 0 and everything else is in its proper place(Monday is 1, Tuesday is 2...so on).
DECODE(to_number(to_char(hire_date ,'D'))-1,
0, 7,
to_number(to_char(hire_date ,'D'))-1);