How to get Previous business day in a week with that of current Business Day using sql server
SELECT DATEADD(DAY, CASE DATENAME(WEEKDAY, GETDATE())
WHEN 'Sunday' THEN -2
WHEN 'Monday' THEN -3
ELSE -1 END, DATEDIFF(DAY, 0, GETDATE()))
I prefer to use DATENAME
for things like this over DATEPART
as it removes the need for Setting DATEFIRST
And ensures that variations on time/date settings on local machines do not affect the results. Finally DATEDIFF(DAY, 0, GETDATE())
will remove the time part of GETDATE()
removing the need to convert to varchar (much slower).
EDIT (almost 2 years on)
This answer was very early in my SO career and it annoys me everytime it gets upvoted because I no longer agree with the sentiment of using DATENAME.
A much more rubust solution would be:
SELECT DATEADD(DAY, CASE (DATEPART(WEEKDAY, GETDATE()) + @@DATEFIRST) % 7
WHEN 1 THEN -2
WHEN 2 THEN -3
ELSE -1
END, DATEDIFF(DAY, 0, GETDATE()));
This will work for all language and DATEFIRST settings.
Select the previous business day by using SQL
SELECT ..
.
.
AND DATE(a.scantime) = (CASE WEEKDAY(CURRENT_DATE)
WHEN 0 THEN SUBDATE(CURRENT_DATE,3)
WHEN 6 THEN SUBDATE(CURRENT_DATE,2)
WHEN 5 THEN SUBDATE(CURRENT_DATE,1)
ELSE SUBDATE(CURRENT_DATE,1)
END)
..
..
Getting SQL to return data ONLY for the last business day
Your method is fine. Your variable definition has DAY,
in it. So:
SET @CREATIONDAY = DATEADD(DAY,
(CASE DATENAME(WEEKDAY, convert(date,GETDATE()))
WHEN 'Sunday' THEN -2
WHEN 'Monday' THEN -3
ELSE -1
END),
GETDATE());
Or, just add the logic into the WHERE
clause:
WHERE (DATENAME(WEEKDAY, GETDATE()) = 'Sunday' AND
CREATION_DATE = DATEADD(DAY, -2, CAST(GETDATE as DATE))
) OR
(DATENAME(WEEKDAY, GETDATE()) = 'Monday' AND
CREATION_DATE = DATEADD(DAY, -3, CAST(GETDATE as DATE))
) OR
(DATENAME(WEEKDAY, GETDATE()) = 'Sunday' AND
CREATION_DATE = DATEADD(DAY, -2, CAST(GETDATE as DATE))
) OR
(DATENAME(WEEKDAY, GETDATE()) NOT IN ('Sunday', 'Monday') AND
CREATION_DATE = DATEADD(DAY, -1, CAST(GETDATE as DATE))
)
Keep last n business days records from today date in SQL Server
You can get the 7th working day from today as
select top(1) cast(dateadd(d, -n + 1, getdate()) as date) d
from (
select n
, sum (case when datename(dw, dateadd(d, -n + 1, getdate())) not in ('Sunday', 'Saturday') then 1 end) over(order by n) wdn
from (
values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11)
)t0(n)
) t
where wdn = 7
order by n;
Generally using on-the-fly tally for a @n -th day
declare @n int = 24;
with t0(n) as (
select n
from (
values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)
) t(n)
), tally as (
select top(@n + (@n/5 +1)*2) row_number() over(order by t1.n) n
from t0 t1, t0 t2, t0 t3
)
select top(1) cast(dateadd(d, -n + 1, getdate()) as date) d
from (
select n
, sum (case when datename(dw, dateadd(d, -n + 1, getdate())) not in ('Sunday', 'Saturday') then 1 end) over(order by n) wdn
from tally
) t
where wdn = @n
order by n;
Need a function to return date of next/Previous business day SQL Server
You have to create a table type variable
first:
CREATE TYPE BusinessDateTableType AS TABLE
(
[WeekDay] VARCHAR(50),
IsBusinessDate BIT
);
Then create the function that takes a table-valued parameter of the above type:
CREATE FUNCTION UDF_GetNextBusinessDay
(
@businessDates BusinessDateTableType READONLY,
@type VARCHAR(10),
@day DATE
)
RETURNS DATE
AS
BEGIN
-- Declare the return variable here
DECLARE @nextBusinessDate DATE
;WITH cte AS (
SELECT CASE
WHEN @type = 'Next' THEN 1
WHEN @type = 'Previous' THEN -1
END AS i
UNION ALL
SELECT CASE
WHEN @type = 'Next' THEN i + 1
WHEN @type = 'Previous' THEN i -1
END AS i
FROM cte
WHERE ABS(i) < 7
)
SELECT TOP 1 @nextBusinessDate = DATEADD(day, i, @day)
FROM cte AS d1
INNER JOIN @businessDates AS d2 ON DATENAME(DW, DATEADD(day, i, @day)) = d2.WeekDay
WHERE d2.IsBusinessDate = 1
ORDER BY ABS(i)
-- Return the result of the function
RETURN @nextBusinessDate
END
EDIT:
We can easily substitute the table-type variable in the UDF with seven BIT
type variables, then use a table variable
inside the UDF and populate it with the values of these variables:
CREATE FUNCTION UDF_GetNextBusinessDay2
(
@IsMonWorkingDay BIT,
@IsTueWorkingDay BIT,
@IsWedWorkingDay BIT,
@IsThuWorkingDay BIT,
@IsFriWorkingDay BIT,
@IsSatWorkingDay BIT,
@IsSunWorkingDay BIT,
@type VARCHAR(10),
@day DATE
)
RETURNS DATE
AS
BEGIN
-- Declare the return variable here
DECLARE @nextBusinessDate DATE
DECLARE @businessDates TABLE ([WeekDay] VARCHAR(50), IsBusinessDate BIT)
INSERT INTO @businessDates VALUES
('Monday', @IsMonWorkingDay),
('Tuesday', @IsTueWorkingDay),
('Wednesday', @IsWedWorkingDay),
('Thursday', @IsThuWorkingDay),
('Friday', @IsFriWorkingDay),
('Saturday', @IsSatWorkingDay),
('Sunday', @IsSunWorkingDay)
;WITH cte AS (
SELECT CASE
WHEN @type = 'Next' THEN 1
WHEN @type = 'Previous' THEN -1
END AS i
UNION ALL
SELECT CASE
WHEN @type = 'Next' THEN i + 1
WHEN @type = 'Previous' THEN i -1
END AS i
FROM cte
WHERE ABS(i) < 7
)
SELECT TOP 1 @nextBusinessDate = DATEADD(day, i, @day)
FROM cte AS d1
INNER JOIN @businessDates AS d2 ON DATENAME(DW, DATEADD(day, i, @day)) = d2.WeekDay
WHERE d2.IsBusinessDate = 1
ORDER BY ABS(i)
-- Return the result of the function
RETURN @nextBusinessDate
END
Using the second version of the UDF with this test data:
DECLARE @type VARCHAR(10) = 'Next'
DECLARE @day DATE = '2014-12-22'
DECLARE @nextBusinessDate DATE
SET @nextBusinessDate = dbo.UDF_GetNextBusinessDay2(1,0,0,0,0,0,1, @type, @day)
SELECT @nextBusinessDate
produces the following result:
2014-12-28
How can I set last business date in SQL Server
declare @LastBizDate as datetime
set @LastBizDate = CASE DATENAME(WEEKDAY, GETDATE())
WHEN 'Monday' THEN GETDATE()-3
WHEN 'Sunday' THEN GETDATE()-2
ELSE GETDATE()-1 END
PRINT @LastBizDate
Add business days to date in SQL without loops
This answer has been significantly altered since it was accepted, since the original was wrong. I'm more confident in the new query though, and it doesn't depend on DATEFIRST
I think this should cover it:
declare @fromDate datetime
declare @daysToAdd int
select @fromDate = '20130123',@DaysToAdd = 4
declare @Saturday int
select @Saturday = DATEPART(weekday,'20130126')
;with Numbers as (
select 0 as n union all select 1 union all select 2 union all select 3 union all select 4
), Split as (
select @DaysToAdd%5 as PartialDays,@DaysToAdd/5 as WeeksToAdd
), WeekendCheck as (
select WeeksToAdd,PartialDays,MAX(CASE WHEN DATEPART(weekday,DATEADD(day,n.n,@fromDate))=@Saturday THEN 1 ELSE 0 END) as HitWeekend
from
Split t
left join
Numbers n
on
t.PartialDays >= n.n
group by WeeksToAdd,PartialDays
)
select DATEADD(day,WeeksToAdd*7+PartialDays+CASE WHEN HitWeekend=1 THEN 2 ELSE 0 END,@fromDate)
from WeekendCheck
We split the time to be added into a number of weeks and a number of days within a week. We then use a small numbers table to work out if adding those few days will result in us hitting a Saturday. If it does, then we need to add 2 more days onto the total.
Finding the first and last business day for every month sql
If you got already a table with all the weekdays only:
select min(datecol), max(datecol)
from BusinessOnlyCalendar
group by year(datecol), month(datecol)
But you should expand your calendar to include all those calculations you might do on date, like FirstDayOfWeek/Month/Quarter/Year, WeekNumber, etc.
When you got a column in your calendar indicating business day yes/no, it's a simple:
select min(datecol), max(datecol)
from calendar
where businessday = 'y'
group by year(datecol), month(datecol)
How to query last 2 business days only
select *
from LetterGenerationTemplateRequest
where createddate >= (
getdate() -
case datename(dw,getdate())
when 'Tuesday' then 5
when 'Monday' then 4
else 3
end
)
--and datename(dw,createdDate) not in ('Saturday','Sunday',datename(dw,getdate()))
and datename(dw,createdDate) not in ('Saturday','Sunday')
;
Related Topics
Changing Precision of Numeric Column in Oracle
Postgresql: Foreign Key/On Delete Cascade
Concatenate/Merge Array Values During Grouping/Aggregation
Is There Something Equivalent to Argmax in SQL
SQL Server 2008 Query to Find Rows Containing Non-Alphanumeric Characters in a Column
Selecting Nth Record in an SQL Query
How to Generate Crud Stored Procedures from a Table in SQL Server Management Studio
How to Order Entries in a Union Without Order By
Regular Expression to Remove Comments from SQL Statement
Mysql: Returning Multiple Columns from an In-Line Subquery
How Different Is Postgresql to MySQL
Convert Integer to Text in SQLite's Select Query
Is MySQL Limit Applied Before or After Order By
Django: Using Custom Raw SQL Inserts with Executemany and MySQL