how do I use getdate() in SSRS while excluding weekends and holidays - getdate

I am trying to run a report for next day by using getdate()+1 but I want to exclude weekends and holidays. To exclude weekends, I included the following in my where statement but it doesn't work. Ideally it should show Monday's results if I am running on Friday. But instead I am getting no results.
Below is my query:
select * from table
where CONVERT(DATE, [Appointment_DateTime]) = CONVERT(DATE, getdate()+1)
and DATEPART(w,CONVERT(DATE, [Appointment_DateTime])) NOT IN (1,7)
I am using not in (1,7) since sunday is the first day of the server so I am excluding sunday and Saturday.

If you want to show Monday data on Friday, you should add three days if it's Friday today:
select *
from table
where CONVERT(DATE, [Appointment_DateTime]) = CONVERT(DATE, getdate() + IIF(DATEPART(w,CONVERT(DATE, [Appointment_DateTime])) = 6, 3, 1))
and DATEPART(w,CONVERT(DATE, [Appointment_DateTime])) NOT IN (1,7)
another approach is to use different conditions for Mon-Thu and Fri:
select *
from table
where CONVERT(DATE, [Appointment_DateTime]) = CONVERT(DATE, GETDATE() + 1)
and DATEPART(weekday,CONVERT(DATE, [Appointment_DateTime])) in (2,3,4,5)
union all
select *
from table
where CONVERT(DATE, [Appointment_DateTime]) = CONVERT(DATE, GETDATE() + 3)
and DATEPART(weekday,CONVERT(DATE, [Appointment_DateTime])) = 6
first part of union will yield rows for Mon-Thu, second one for Fridays

Related

how to get year and month into number oracle

i'm trying to get sysdate year and month into number or char.
I'd want something like this:
202107
or last month
202106
i tried this code:
select trunc(add_months(sysdate, -1), 'MM') from dual;
please help, thanks
Convert it to a string and then to a number:
SELECT TO_NUMBER(TO_CHAR(ADD_MONTHS(SYSDATE,-1), 'YYYYMM'))
FROM DUAL;
Or, you can use extract and wrap it in a sub-query so you do not need to repeat adding the months:
SELECT EXTRACT(YEAR FROM dt) * 100 + EXTRACT(MONTH FROM dt)
FROM (
SELECT ADD_MONTHS(SYSDATE, -1) AS dt
FROM DUAL
)
Like
SELECT EXTRACT(year from sysdate) * 100 + EXTRACT(month from sysdate)
If you want to scroll around, manipulate the date before you extract from it, rather than minusing after you extract (gets tricky to e.g. go back a month if the date is in jan)
--will work for jan 2021
SELECT EXTRACT(year from ADD_MONTHS(somedate, -1)) * 100 + EXTRACT(month from ADD_MONTHS(somedate, -1))
--won't work for jan 2021
SELECT EXTRACT(year from somedate) * 100 + (EXTRACT(month from somedate) - 1)
TRUNC is a device that "rounds" a date to a particular interval, such as "trimming the time off a datetime" or "making any day of the week back to the date that was the start of the week" - very useful for all sorts of stuff like "total sales by month - SUM(sale) GROUP BY TRUNC(saledate, 'mm')" but it keeps all the components of the date (the day, the hour, the minute etc) so it isn't what you want.

Return records from todays month + 6

how can i return records sales from todays + 6 months.
Example:
Today´s month: May-2018.
Today´s month + 6: Nov-2018
So, i want a function to retrieve records from Table_Date, from November (1 to 30).
Thanks.
Use the TRUNC and ADD_MONTHS functions:
SELECT *
FROM sales
WHERE SalesDate >= ADD_MONTHS( TRUNC( SYSDATE, 'MM' ), 6 )
AND SalesDate < ADD_MONTHS( TRUNC( SYSDATE, 'MM' ), 7 );
You have SQL server and oracle, it cant be both.
This is for SQL Server (though logic would work in ORACLE, but syntax may not)
This is to get 6 months from today
SELECT DATEADD(MM, 6, GETDATE())
Added extra code here for more details after looking at question more:
I am using variables to do the calculations to make it easier to understand but you could do it all inline (but harder to read).
This script gets a date 6 months from now, takes that month and finds the first day of that month, and then the last day of that month so you can use those 2 dates in a where clause logic.
DECLARE #NewMonth AS VARCHAR(10)
DECLARE #NewYear AS VARCHAR(10) -- in case adding months goes to next year
SELECT #NewMonth = DATEPART(MONTH, DATEADD(MM, 6, GETDATE())),
#NewYear = DATEPART(YEAR, DATEADD(MM, 6, GETDATE()))
DECLARE #FirstOfMonth AS DATE = #NewMonth + '/1/' + #NewYear
-- for start of month check we can just hard code one in it, for end of month we cant because we dont know how many days are in it
SELECT #FirstOfMonth, DATEADD(DAY, -1, DATEADD(MONTH, 1, #FirstOfMonth)) AS LastDayOfMontbh

Just the month january not working

In this query I found the weeks of month, for example november begin 1th Wednesday and ends sunday 5.
These are the first week on november.
SELECT * FROM (
WITH days AS
(SELECT to_date('01012017','ddmmyyyy') + level-1 date_in
FROM dual
CONNECT BY level < 32)
SELECT date_in,
TO_CHAR(date_in,'IW') - TO_CHAR(TRUNC(date_in,'MM'),'IW') + 1 week_number
FROM days) where week_number = 1;
The week_number can change depending of the weeks of the month, but in January is not working.
Your requirement is not clear for me but perhaps you are looking for this:
SELECT TRUNC (next_day(TRUNC(TO_DATE('20022017','ddmmyyyy'), 'mm'),'monday') - 1), 'IW') AS first_week
FROM dual;
I'm still a bit unclear as to what you're looking for, but perhaps the following query will help you on your way:
WITH YEAR_START AS (SELECT TO_DATE('01012017', 'DDMMYYYY') AS FIRST_DAY_OF_YEAR
FROM DUAL),
MONTH_START AS (SELECT FIRST_DAY_OF_YEAR AS FIRST_DAY_OF_MONTH
FROM YEAR_START
UNION ALL
SELECT ADD_MONTHS(FIRST_DAY_OF_YEAR, LEVEL) AS FIRST_DAY_OF_MONTH
FROM YEAR_START
CONNECT BY LEVEL <= 11),
MONTH_START_AND_END AS (SELECT FIRST_DAY_OF_MONTH,
ADD_MONTHS(FIRST_DAY_OF_MONTH, 1) - INTERVAL '1' DAY AS LAST_DAY_OF_MONTH
FROM MONTH_START),
ABS_MONTH_WEEKS AS (SELECT FIRST_DAY_OF_MONTH,
LAST_DAY_OF_MONTH,
TO_NUMBER(TO_CHAR(FIRST_DAY_OF_MONTH, 'IW')) AS ABS_FIRST_WEEK_OF_MONTH,
TO_NUMBER(TO_CHAR(LAST_DAY_OF_MONTH, 'IW')) AS ABS_LAST_WEEK_OF_MONTH
FROM MONTH_START_AND_END),
REL_MONTH_WEEKS AS (SELECT a.*,
1 AS REL_FIRST_WEEK_OF_MONTH,
ABS_LAST_WEEK_OF_MONTH - CASE
WHEN ABS_FIRST_WEEK_OF_MONTH > ABS_LAST_WEEK_OF_MONTH THEN 0
ELSE ABS_FIRST_WEEK_OF_MONTH-1
END AS REL_LAST_WEEK_OF_MONTH
FROM ABS_MONTH_WEEKS a)
SELECT *
FROM REL_MONTH_WEEKS;
Best of luck.

How to get data from first day of the month until yesterday

does anyone know the query to get data from first day of the month until yesterday? I Try using query below but the problem is when today is the first day of the month, so the value become between 20170201 and 20170131
select * from a where to_char(DATE,'yyyymmdd') BETWEEN to_char(sysdate,'yyyymm')||'01' and to_char(sysdate-1,'yyyymmdd')
Ex: if today is 01-02-2017 i want to select the data from 01-01-2017 until 31-01-2017, but if today is 13-02-2017 i want to select the data from 01-02-2017 until 12-02-2017, thank's before
This question has been updated with your new logic. The query below will retain records under the following conditions:
someDate falls between the first day and yesterday of the current month, or
someDate, when today is the first of the month, falls anywhere in the previous month
SELECT *
FROM yourTable
WHERE someDate BETWEEN CASE WHEN EXTRACT(DAY FROM SYSDATE) = 1
THEN TRUNC(SYSDATE-1, 'MONTH')
ELSE TRUNC(SYSDATE, 'MONTH') END AND
CASE WHEN EXTRACT(DAY FROM SYSDATE) = 1
THEN TRUNC(SYSDATE, 'MONTH') - 1
ELSE TRUNC(SYSDATE - 1) END
This query assumes that you have a DATE column called someDate.

Alternate for decode function

I have a table 'Holiday' which lists a set of holiday details.If i specify a date,I should obtain a result date after 5 days of specified date.If there is holiday in between it should exclude them and display the non holiday date.I have table named holiday which includes holiday date,holiday type|(weekly off,local holiday).Now i have used nested decode for continuous holiday checking.Tell me how this can be changed in case function.
DECODE
(date,
holidaydate, DECODE
(date + 1,
holidaydate + 1, DECODE
(date + 2,
holidaydate + 2, DECODE
(date + 3,holidaydate+3,date+4,date+3),date+2),date+1),date);
This can be achieved with a simple subquery which counts the number of holiday dates between a specified date and date+5. The following will return a date that is five non-holiday days in the future:
testdate+(select 5+count(1)
from holiday
where holidaydate between testdate
and testdate + 5)
Simply change both "5"s so another number to change the evaluation period.
SQLFiddle here
Edit - based on comment below, my code doesn't evaluate any days after the fifth day. This would probably be much easier with a function, but the following cte-based code will work also:
with cte as ( (select alldate,holidaydate
from (select to_date('20130101','yyyymmdd')+level alldate
from dual
connect by level < 10000 -- adjust for period to evaluate
) alldates
left join holiday on alldate=holidaydate) )
select
testdate,test_plus_five
from (
select
alldate test_plus_five,testdate,
sum(case when holidaydate is null
then 1
else 0 end) over (partition by testdate order by alldate) lastday
from
cte,
testdates
where
alldate >= testdate
group by
alldate,holidaydate,testdate)
where
lastday = 6
This script builds a calendar table so it can evaluate each day (holiday or non-holiday); then we get a running count of non-holiday days, and use the sixth one.
SQLFiddle here
AFAIK, You can use CASE alternative to DECODE in Oracle
CASE [ expression ]
WHEN condition_1 THEN result_1
WHEN condition_2 THEN result_2
...
WHEN condition_n THEN result_n
ELSE result
END
Finally i found the optimal solution.Thanks for ur response guys. SELECT dt FROM
(SELECT dt FROM (SELECT TO_DATE('15-AUG-2013','dd-mon-yyyy')+LEVEL dt FROM DUAL
CONNECT BY LEVEL < 30)
WHERE
(SELECT COUNT (*) FROM mst_holiday WHERE holidaydate = dt) = 0 )
where rownum=1

Resources