This code works when run as SQL Query in Microsoft SQL Server Management Studio 2008 but when is set as Job step then works only second condition (update when is not last day of month). What is wrong with this code?
--set next invoice date
declare #data nvarchar(10) --invoice date
set #data = CONVERT (date, GETDATE());
update table
set invoice_date = case when day(DATEADD(day,1,#data)) = 1 then --is last day of month
(SELECT convert(date,DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0)))) -- set inovice date as last day of next month
else --is not last day of month
(select DATEADD(MM,1,#data)) --add one month to inovice date
end
where status = 'current' and invoice_date = #data -- only for current inovices
Try this. First condition will work on every month last day only.
--set next invoice date
DECLARE #data NVARCHAR(10) --invoice date
SET #data = CONVERT (DATE, GETDATE());
UPDATE table
SET invoice_date = CASE WHEN DAY(DATEADD(DAY,1,#data)) = 1
THEN --is last day of month
CAST( DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#data)+2,0)) AS DATE) -- set inovice date as last day of next month
ELSE --is not last day of month
(DATEADD(MM,1,#data)) --add one month to inovice date
END
WHERE status = 'current' AND invoice_date = #data -- only for current inovices
Related
I am trying to use a predefined INT value giving 1 or 0 as being a business day or not to count the rolling business days sequence. I have tried a lot of different code and checked out different posts here but none are specific enough to work with mine.
The predefined INT value is "business_day_flag_int". This comes from converting the calculations giving me "day_business_day_flag" which is a bit value. Currently Saturday/Sunday and Banking holidays trigger a 0 for "day_business_day_flag" and Mon-Fri being non holiday give it a 1 value.
How can I get this to work in an Update table that I can add to the rest of my table generation file? If more information is needed let me know.
I've tried a bunch of different alterations and variations of what I have here. If I remove date values it gives me an int value for all rows in the column of roughly 12600 business days. If I use with the date range it gives me
DECLARE #StartDate DATETIME = '01/01/2000' --Starting value of Date Range
DECLARE #EndDate DATETIME = '01/01/2050' --End Value of Date Range
DECLARE
#DayOfWeekInMonth INT,
#DayOfWeekInYear INT,
#DayOfQuarter INT,
#WeekOfMonth INT,
#CurrentYear INT,
#CurrentMonth INT,
#CurrentQuarter INT
DECLARE #CurrentDate AS DATETIME = #startDate
SET #CurrentMonth = DATEPART(MM, #CurrentDate)
SET #CurrentYear = DATEPART(YY, #CurrentDate)
SET #CurrentQuarter = DATEPART(QQ, #CurrentDate)
UPDATE [EDW_MDM].[dbo].[CALENDAR_DIM] SET
business_day_flag_int = Convert(INT, day_business_day_flag)
UPDATE [EDW_MDM].[dbo].[CALENDAR_DIM] SET
rolling_business_day_sequence = (SELECT count(business_day_flag_int) FROM [EDW_MDM].[dbo].[CALENDAR_DIM]
WHERE business_day_flag_int = 1 and
day_date between #StartDate and #CurrentDate)
I want the column "rolling_business_day_sequence" to count sequentially business days past. For example row 1 = 1, row 2 = 2, etc. Until the end of my calendar.
Update 1: Edited the line of code to
UPDATE [EDW_MDM].[dbo].[FCFCU_CALENDAR_DIM] SET
rolling_business_day_sequence = datediff(day,#StartDate,day_date) WHERE day_business_day_flag = 1
This gave me counting days and set rolling_business_day_sequence row values to null where not having day_busienss_day_flag = 1 and still counting them instead of not counting them. How can I make it not add the day?
Consider a window function sum on your WHERE conditions to cumulatively count all instances of business_day_flag_int = 1 within specified date range. However, to use window functions in UPDATE, a CTE or subquery is required.
WITH CTE AS
(
SELECT ID, SUM(CASE WHEN day_date BETWEEN #StartDate AND #CurrentDate
AND business_day_flag_int = 1
THEN 1
ELSE 0
END) OVER (ORDER BY day_date) AS running_sequence
FROM [EDW_MDM].[dbo].[CALENDAR_DIM]
)
UPDATE t
FROM [EDW_MDM].[dbo].[CALENDAR_DIM] t
JOIN CTE ON t.ID = CTE.ID
SET t.rolling_business_day_sequence = CTE.running_sequence
I require to calculate the Last day of previous week and last of day current week in Multidimensional Cube.I need to have in Cube calculation
For example: I have Time dimension with Hierarchies as below
Year-Quarter-month-date
Year-Quarter-month
Year-Quarter-week
Year-Week.
I have Time Week dimension- which has hierarchy Time-week and my View show below data
Week-2018-W18
WeekNumberOfYear-2018-W18
Year-18
YearNo-2018
StartDate-2018-04-30 00:00:00.000
EndDate-2018-05-06 23:59:59.997
CurrentWeek-1
Current Week is set flag set. As per above data.
If I run the report today(03/05/2018)-Thursday.
previous week last working day should show- 2018-04-27- Friday
Current week last day should be-2018-05-04-Friday.
Please let me know how to calculate the dates via cube calculation, I am able to find the previous year with Parallel Period function.
This will work.
You need to just mention last day name.
Declare #Pre_last_Dayname datetime, #cur_last_Dayname datetime, #date datetime, #found datetime, #dayname varchar(14)
set #date = GETDATE()
set #dayname = 'Friday'
WHILE #Pre_last_Dayname is null
BEGIN
set #date = #date - 1
select #Pre_last_Dayname = #date
where DATENAME(dw,#date) = #dayname
END ;
set #date = GETDATE()
WHILE #cur_last_Dayname is null
BEGIN
select #cur_last_Dayname = #date
where DATENAME(dw,#date) = #dayname
set #date = #date + 1
END
select concat(format(#Pre_last_Dayname ,'dd/MM/yyyy'),'-',DATENAME(dw,#Pre_last_Dayname) )'last_day of_last_week'
, concat(format(#cur_last_Dayname ,'dd/MM/yyyy'),'-',DATENAME(dw,#cur_last_Dayname) )'last_day of_current_week'
, concat(format(GETDATE() ,'dd/MM/yyyy'),'-',DATENAME(dw,GETDATE()) )'current_date'
Use this for getting previous week date.
Declare #CurWkFromDate DateTime,
#CurWkTodate DateTime,
#PrvWkFromdate DateTime,
#PrvWkTodate DateTime,
#Ondate DateTime = '2018-05-03'
select #CurWkFromDate = dbo.Lynk_Current_WeekStartDate(#Ondate),
#CurWkTodate = dbo.Lynk_Current_WeekEndDate(#Ondate),
#PrvWkFromdate = dbo.Lynk_Current_WeekStartDate(Dateadd(dd,-1,#CurWkFromDate)),
#PrvWkTodate = dbo.Lynk_Current_WeekEndDate(#PrvWkFromdate)
select #CurWkFromDate,#CurWkTodate,#PrvWkFromdate,#PrvWkTodate
First create the function in DB and try this.
CREATE Function Lynk_Current_WeekStartDate
(
#processDate datetime
)
Returns DateTime
As
Begin
Declare #FromDate DateTime
Set #FromDate=dateadd(d,0,dateadd("ww",datediff(wk,'01/01/1900',DATEADD(dd,-1,#processDate)),'01/01/1900')) --Monday
Return(#FromDate)
End
CREATE Function Lynk_Current_WeekEndDate
(
#Processdate datetime
)
Returns DateTime
As
Begin
Declare #FromDate DateTime
Declare #ToDate DateTime
Set #FromDate=dbo.Lynk_Current_WeekStartDate(#Processdate)
Set #Todate=dateadd(ss,-1,dateadd(d,5,#FromDate))
Return(#ToDate)
End
Example:
select dbo.Lynk_Current_WeekStartDate('2018-05-03')
select dbo.Lynk_Current_WeekEndDate('2018-05-03')
How can I calculate the date of the upcoming second Monday in January relative to the current date using a SQL query?
Below is a query that I have which doesn't work if the current date is of the same year but prior to the upcoming second Monday of January.
declare #secondMondayOfJan date = dateadd(day , ((17 - datepart(dw,current_timestamp)) % 7) + 6, current_timestamp)
IF current_timestamp > #secondMondayOfJan
select #secondMondayOfJan as Deadline
ELSE
declare #firstDayOfNextYear date = datefromparts(year(current_timestamp)+1,1,1)
set #secondMondayOfJan = dateadd(day, ((17 - datepart(dw,#firstDayOfNextYear)) % 7) + 6, #firstDayOfNextYear)
select #secondMondayOfJan as Deadline
This looks quite verbose, but hopefully makes the logic clear, and doesn't depend on any particular settings (such as DATEFIRST or language settings):
;With Nums(n) as (
select 0 union all select 1 union all select 2 union all select 3
union all select 4 union all select 5 union all select 6
), ThisAndNext as (
select
DATEADD(year,DATEDIFF(year,'20010101',GETDATE()),'20010108') as SecondWeek,
0 as Choose
union all
select
DATEADD(year,DATEDIFF(year,'20010101',GETDATE()),'20020108'),
1
), Combined as (
select DATEADD(day,n,SecondWeek) as Possible,Choose
from ThisAndNext cross join Nums
)
select top 1 Possible from Combined
where Possible >= DATEADD(day,DATEDIFF(day,0,GETDATE()),0)
and DATEPART(weekday,Possible) = DATEPART(weekday,'20150504')
order by Choose
Nums is just a small set of numbers - it can be replaced with a select from a numbers table, if you already have one.
ThisAndNext finds the 8th of this year and next year, as two separate rows.
Combined adds between 0 and 6 days onto the 8th of this year and next.
Finally, we select the first date from Combined that is (the following bullet points correspond to the lines of the WHERE clause)
equal to or greater than today's date (using another instance of the DATEADD/DATEDIFF pattern to remove the time element from GETDATE())
on a Monday (by comparing it to an arbitrary, well known Monday)
by preference, from this year rather than next
All taken together, this means that we have selected a future (or current) day that falls between the 8th and the 14th of January that is a Monday. If you don't want "today" to be a possible result, just change the >= comparison towards the end to be a >.
The logic behind this code is:
get the first day of the current year
get the first day of the next year
find the 2nd weekday of jan of the current year
find the 2nd weekday of jan of the next year
compare the current date if is greater than or less than or equal and based on this set the deadline to the correct 2nd weekday
It's setup to retrieve the 2nd monday, but changing the value of the variable #dw between 1 to 7, you will get the others weekday
(1 = Sunday, 2 = Monday, 3 = Tuesday, 4 = Wednesday, 5 = Thursday, 6 = Friday, 7 = Saturday)
You can play with this code at:
http://rextester.com/TVKYW75798
/*
THIS STATEMENT WILL RETURN THE 2ND WEEKDAY OF JAN BASED ON CURRENT DATE.
IF CURRENT_DATE = 2ND WEEKDAY OF JAN
THEN DEADLINE = CURRENT_DATE
IF CURRENT_DATE < 2ND WEEKDAY OF JAN
THEN DEADLINE = 2ND WEEKDAY OF JAN (CURRENT YEAR)
IF CURRENT_DATE > 2ND WEEKDAY OF JAN
THEN DEADLINE = 2ND WEEKDAY OF JAN (NEXT YEAR)
YOU CAN PLAY WITH VARIABLE #date and #dw TO TEST.
I LEAVE COMMENTED IN THE CODE FOUR SCENARIOS (YEAR 2015)
WHERE YOU WILL BE ABLE TO CHECK THE CONDITIONS ABOVE.
2015-01-12 WAS THE 2ND MONDAY OF JAN
*/
DECLARE #date DATE = GETDATE()
-- SET #date = '2015-01-01'
-- SET #date = '2015-01-11'
-- SET #date = '2015-01-12'
-- SET #date = '2015-01-13'
DECLARE #currentYearFirstDay DATE = CAST(datepart(yy, #date) AS VARCHAR) + '-01-01'
DECLARE #nextYearFirstDay DATE = DATEADD(yy, 1, #currentYearFirstDay)
DECLARE #d DATE
DECLARE #secondWeekdayCurrentYear DATE
DECLARE #secondWeekdayNextYear DATE
DECLARE #dw INT = 2 /*USE VALUES FROM 1 TO 7, WHERE 1 = SUNDAY AND 7 = SATURDAY*/
DECLARE #weekOfYear INT = DATEPART(ww,#d)
DECLARE #weekDay INT = DATEPART(dw,#d)
DECLARE #checkNextYear INT = 0
SET #d = #currentYearFirstDay
GOTO GET_2nd_WEEKDAY_FROM_FIRST_DAY_OF_YEAR
GET_2nd_WEEKDAY_FROM_FIRST_DAY_OF_YEAR:
BEGIN
SET #weekDay = DATEPART(dw, #d)
/*FIRST DAY OF YEAR GREATER THAN WEEKDAY, THEN 2nd WEEKDAY WILL BE THE 3rd WEEK*/
IF #weekDay > #dw
BEGIN
SET #d = DATEADD(ww, 2, #d)
END
/*FIRST DAY OF YEAR LESS THAN OR EQUAL WEEKDAY, THEN 2nd WEEKDAY WILL BE THE 2nd WEEK*/
ELSE
BEGIN
SET #d = DATEADD(ww, 1, #d)
END
IF #checkNextYear = 0
BEGIN
SET #secondWeekdayCurrentYear = DATEADD(dw, -(#weekDay - #dw), #d)
SET #d = #nextYearFirstDay
SET #checkNextYear = 1
GOTO GET_2nd_WEEKDAY_FROM_FIRST_DAY_OF_YEAR
END
ELSE
BEGIN
SET #secondWeekdayNextYear = DATEADD(dd, -(#weekDay - #dw), #d)
GOTO EXIT_BLOCK
END
END
EXIT_BLOCK:
SELECT CASE
WHEN #date > #secondWeekdayCurrentYear
THEN #secondWeekdayNextYear
ELSE
CASE
WHEN #date = #secondWeekdayCurrentYear
THEN #date
ELSE #secondWeekdayCurrentYear
END
END AS DEADLINE
I have a table named Locations that has column named effective_date with many dates from many years, and I want to retrieve only those that are not on the first day of the month or the last day of that month.
Here is a SQL Fiddle Demo with the detail below.
Generate a table and some sample test data:
CREATE TABLE Locations(
effective_date DATETIME
)
INSERT INTO Locations
VALUES('2014-01-01') -- First day so we would expect this NOT to be returned
INSERT INTO Locations
VALUES('2014-01-02') -- This should be returned
INSERT INTO Locations
VALUES('2014-01-31') -- Last day of January so this should NOT be returned
Then the query below works out the last day of the month for each date in the table, records are only returned is if the effective_date is not the first or last day of the month as calculated.
SELECT effective_date FROM Locations
WHERE -- not the first day (the easy bit!)
DATEPART(day, effective_date) <> 1
-- not the last day (slightly more complex)
AND DATEPART(day, effective_date) <>
DATEPART(day, DATEADD(second,-1,DATEADD(month, DATEDIFF(month,0,effective_date)+1,0)))
When executed only January, 02 2014 00:00:00+0000 is returned as expected.
The clever bit here is the function to calculate the last day of the current month when given a date, lets examine that and break it down:
DECLARE #sampleDate DATETIME
SET #sampleDate = '2014-01-02'
-- Calculate the number of months between '1900-01-01' and the #sampleDate
-- +1 as we want to shift into the following month so we can work back:
SELECT DATEDIFF(month,0,#sampleDate) + 1
-- Result --> 1369
-- Create a new date by adding the result of the previous step in
-- months to '1900-01-01'
SELECT DATEADD(month, DATEDIFF(month,0,#sampleDate)+1,0)
-- Result --> '2014-02-01' (giving first day of the following month)
-- Subtract one second from this
SELECT DATEADD(second,-1,DATEADD(month, DATEDIFF(month,0,#sampleDate)+1,0))
-- Result --> '2014-01-31 23:59:59' (giving the very end of the original month)
-- Finally extract the day of the month
SELECT DATEPART(day, DATEADD(second,-1,DATEADD(month, DATEDIFF(month,0,#sampleDate)+1,0)))
-- Result --> 31
If your effective_date columns is of type date, then this SQL query will return all rows with a non-null effective_date value that is other than the 1st or last day of the month:
select t.effective_date , count(*)
from dbo.foo t
where 1 = 1 -- just for clarity
-- after the 1st day of the month
and t.effective_date > dateadd(day ,
1-day( t.effective_date ) ,
t.effective_date
)
-- and prior to the last day of the month
and t.effective_date < dateadd( day ,
-day( dateadd(month,1,t.effective_date) ) ,
dateadd(month,1,t.effective_date)
)
If your column carries a time component with it, that is, any of:
datetime
smalldatetime
datetime2
datetimeoffset
You'll want to cover your bases and modify the query, something like
select *
from dbo.foo t
where 1=1 -- added for clarity
-- effective date on or after the 2nd of the month
and t.effective_date >= convert(date,
dateadd(day ,
2-day( t.effective_date ) ,
t.effective_date
)
)
-- and prior to the last day of the month
and t.effective_date < convert(date,
dateadd(day,
-day( dateadd(month,1,t.effective_date) ) ,
dateadd(month,1,t.effective_date)
)
)
The first day of the month will always be 1.
You should be able to adapt this to find the last day of the current month:
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))
Source: http://blog.sqlauthority.com/2007/08/18/sql-server-find-last-day-of-any-month-current-previous-next/
T-SQL to display dates in a month for only first & last day. Also display dates in month excluding first & last day.
declare #EndOfMonth as DateTime
set #EndOfMonth = ( SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0)) )
select #EndOfMonth as EndOfMonths
declare #EndOfMonthMinus1 as DateTime
set #EndOfMonthMinus1 = (SELECT DATEAdd(DAY, -1, #EndOfMonth) )
select #EndOfMonthMinus1 as EndOfMonths
declare #BeginingOfMonth as DateTime
set #BeginingOfMonth = (SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(GETDATE())-1),GETDATE()),101))
select #BeginingOfMonth as EndOfMonths
declare #BeginingOfMonthPlus1 as DateTime
set #BeginingOfMonthPlus1 = (SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(GETDATE())-2),GETDATE()),101))
select #BeginingOfMonthPlus1 as EndOfMonths
-- select dates in month exclude first and last day
SELECT TOP 1000 [effective_date]
FROM [Locations]
where effective_date <= #EndOfMonthMinus1
and effective_date >= #BeginingOfMonthPlus1
-- select only first of month and last of month
SELECT TOP 1000 [effective_date]
FROM [Locations]
where [effective_date]<= #EndOfMonth
and [effective_date] >= #EndOfMonthMinus1
and [effective_date] >= #BeginingOfMonth
and [effective_date] <= #BeginingOfMonthPlus1
Hope this helps!
Initial Point:
I create a calender table with a function (see below). I use this table e.g. to sum entries for each week in the current year.
Problem:
The calculations are wrong for the first week, since the last week in the year has the value 1 as well as the first week in the year.
Question:
Since the calender table is used for many different queries it is not possible to solve this with just a 'Where' Clause modification. Is it possible to create a calender table where the weeks are just continuous including the last week?
FUNCTION [dbo].[fct_Days_Periode](#startDate datetime, #endDate datetime) RETURNS #RET TABLE
( DateA datetime,
Year as YEAR(DateA),
QuarterNr as DATEPART(quarter, DateA),
Quarter as 'Quarter '+CAST(DATEPART(quarter, DataA) as varchar(10)),
MonthNr as MONTH(DataA),
MonthA as DATENAME(month, DateA),
KW as DATEPART(ISO_WEEK, DataA),
WeekdayA as DATENAME(weekday, DataA)
)
AS
BEGIN
WHILE #startDate<=#endDate
BEGIN
INSERT INTO #RET (DataA) VALUES (#startDate)
SET #startDate=DATEADD(day, 1, #startDate)
END
RETURN
END