Im looking to write a function which declares a variable #StartDate to be the first of January but the year to be the year that you run the script(current year) which means the year can change but the day and month cant.
Anyone know how to do this ?
Example code:
IF #DATE_TYPE = 'FIRST QUARTER'
BEGIN
SET #START_DATE = 01/01/'Current Year'
SET #END_DATE = 31/03/'Current Year'
END
For SQL 2012 and above versions,
SELECT DATEFROMPARTS (YEAR(GETDATE()), 1, 1)
SELECT DATEFROMPARTS (YEAR(GETDATE()), 03, 31)
For All versions,
SELECT CAST('01 JAN '+CAST(DATEPART(YY,GETDATE()) AS NVARCHAR) AS DATETIME)
SELECT CAST('31 MAR '+CAST(DATEPART(YY,GETDATE()) AS NVARCHAR) AS DATETIME)
I think you can do something like this (it's better to use convert() when you define dates and not implicit conversion):
SET #START_DATE = CONVERT(datetime, CAST(YEAR(GETDATE()) AS VARCHAR(4)) + '0101', 112)
SET #END_DATE = CONVERT(datetime, CAST(YEAR(GETDATE()) AS VARCHAR(4)) + '0331', 112)
If youre using SQLSERVER 2012, you can use DATEFROMPARTS
DECLARE #START_DATE DATE,
#END_DATE DATE
SELECT #START_DATE = DATEFROMPARTS(YEAR(GETDATE()), 1, 1) ,
#END_DATE = DATEFROMPARTS(YEAR(GETDATE()), 03, 31)
SELECT #START_DATE [start_date] ,
#END_DATE [end_date]
Result:
start_date end_date
---------- ----------
2017-01-01 2017-03-31
(1 row(s) affected)
DECLARE #Day VARCHAR(10) = '1stQUARTER' --Give the quarter name condiations like 1stQUARTER,2ndQUARTER,3rdQUARTER,4thQuarter
IF (#Day = '1stQUARTER')
BEGIN
SELECT CASE
WHEN DATENAME(QUARTER, getdate()) - 1 = 1
THEN DATEADD(qq, DATEDIFF(qq, 0, GETDATE()) - 1, 0)
END AS StartDayQuarter
,CASE
WHEN DATENAME(QUARTER, getdate()) - 1 = 1
THEN DATEADD(dd, - 1, DATEADD(qq, DATEDIFF(qq, 0, GETDATE()), 0))
END AS EndDayQuarter
END
ELSE IF (#Day = '2ndQUARTER')
BEGIN
SELECT CASE
WHEN DATENAME(QUARTER, getdate()) = 2
THEN DATEADD(qq, DATEDIFF(qq, 0, GETDATE()), 0)
END AS FirstDayQuarter
,CASE
WHEN DATENAME(QUARTER, getdate()) = 2
THEN DATEADD(mm, + 3, DATEADD(dd, - 1, DATEADD(qq, DATEDIFF(qq, 0, GETDATE()), 0)))
END AS LasttDayQuarter
END
ELSE IF (#Day = '3rdQUARTER')
BEGIN
SELECT CASE
WHEN DATENAME(QUARTER, getdate()) + 1 = 3
THEN DATEADD(qq, DATEDIFF(qq, 0, GETDATE()) + 1, 0)
END AS FirstDayQuarter
,CASE
WHEN DATENAME(QUARTER, getdate()) + 1 = 3
THEN DATEADD(mm, + 6, DATEADD(dd, - 1, DATEADD(qq, DATEDIFF(qq, 0, GETDATE()), 0)))
END AS LasttDayQuarter
END
ELSE IF (#Day = '4thQuarter')
BEGIN
SELECT CASE
WHEN DATENAME(QUARTER, getdate()) + 2 = 4
THEN DATEADD(qq, DATEDIFF(qq, 0, GETDATE()) + 2, 0)
END AS FirstDayQuarter
,CASE
WHEN DATENAME(QUARTER, getdate()) + 2 = 4
THEN DATEADD(mm, + 9, DATEADD(dd, - 1, DATEADD(qq, DATEDIFF(qq, 0, GETDATE()), 0)))
END AS LasttDayQuarter
END
ELSE
BEGIN
PRINT 'Enter Valid Quarter Name'
END
OutPut
FirstDayQuarter |LasttDayQuarter
--------------------------------------------
2017-01-01 00:00:00.000 |2017-03-31 00:00:00.000
In Sql 2012+, you could use Datefromparts
IF #DATE_TYPE = 'FIRST QUARTER'
BEGIN
SET #START_DATE = datefromparts(year(getdate()), 1,1)
SET #END_DATE = datefromparts(year(getdate()), 3,31)
END
If you want to get the fisrt date and the last date of a quarter, then use it
DECLARE #CurrentDate datetime = '2017-07-01' -- or getdate() or any date
SELECT datefromparts(year(#CurrentDate),
datepart(quarter, #CurrentDate) * 3 - 2,1) AS StartDate,
EOMONTH(datefromparts(year(#CurrentDate),
datepart(quarter, #CurrentDate) * 3 , 1)) AS EndDate
DECLARE #START_DATE DATETIME
DECLARE #END_DATE DATETIME
DECLARE #DATE_TYPE VARCHAR(500)
DECLARE #YEAR VARCHAR(4)
SET #DATE_TYPE = 'FIRST QUARTER' -- SAMPLE PARAMETER
SET #YEAR = CAST(YEAR(GETDATE()) AS VARCHAR(4))
DECLARE #tbl TABLE ([QUARTER] VARCHAR(50), StartMonth VARCHAR(2), EndMonth VARCHAR(2))
INSERT INTO #tbl ([QUARTER], StartMonth, EndMonth)
SELECT 'FIRST QUARTER', '1', '3'
UNION ALL
SELECT 'SECOND QUARTER', '4', '6'
UNION ALL
SELECT 'THIRD QUARTER', '7', '9'
UNION ALL
SELECT 'FOURTH QUARTER', '10', '12'
SELECT #START_DATE = StartMonth + '/1/' + #YEAR,
#END_DATE = DATEADD(DD, -1, (DATEADD(mm, 1, EndMonth + '/1/' + #YEAR)))
FROM #tbl
WHERE [QUARTER] = #DATE_TYPE
Related
I've written the following query...but I am having a hard time converting it into a function because of a couple reasons...(1) because it contains dynamic SQL and I'm not sure if Functions allow dynamic SQL, and (2) because I am using a temp table to store the output data. I tried converting it to a table variable with no luck. The point of the query is to take any two datetime ranges and an increment type (month, day, year, hour, whatever) and spits out a table of date ranges that include the provided range.
The reason for the query is because I have to write a lot of reports for report server, and many times the report requests want break downs by hour, day, week, month, etc, and I constantly have to write the same query over and over to produce a table of date ranges. I use these tables to left join to so that my final output does not skip any date ranges in case there is no data for that range, it will still fill in zero's and graph/chart out properly.
I don't think there's any way to make this code work in a function, unless there is a completely different way to write it (EDIT, SEE UPDATE BELOW)...I'm sure I could go the long complex route of having some sort of long case statement that instead just had each increment type (second, minute, hour, day, week, month, quarter, year) and then I could eliminate the dynamic SQL. And maybe I could use recursive CTE's and eliminate the while loop. But I don't have any experience with those.
Here's the code:
DECLARE #DateFrom DATETIME = '2017-01-01',
#DateTo DATETIME = '2017-02-02 23:59:59.997',
#Increment VARCHAR(20) = 'mm'
DECLARE #SQL NVARCHAR(MAX) = NULL
IF OBJECT_ID('tempdb..#DateRange') IS NOT NULL DROP TABLE #DateRange --SELECT * FROM #DateRange
CREATE TABLE #DateRange (BeginDate DATETIME, EndDate DATETIME)
SELECT #SQL = '
DECLARE #TargetDate DATETIME = ''' + CONVERT(VARCHAR, #DateFrom, 121) + '''
IF DATEDIFF('+ #Increment +', ''' + CONVERT(VARCHAR, #DateFrom, 121) + ''', ''' + CONVERT(VARCHAR, #DateTo, 121) + ''') > 2000 RETURN
WHILE (1=1)
BEGIN
INSERT INTO #DateRange
SELECT BeginDate = DATEADD('+ #Increment +', DATEDIFF('+ #Increment +', 0, #TargetDate) , 0)
, EndDate = DATEADD(ms, -3, DATEADD('+ #Increment +', DATEDIFF('+ #Increment +', 0, #TargetDate) + 1, 0))
SET #TargetDate = DATEADD('+ #Increment +', 1, #TargetDate)
IF #TargetDate > ''' + CONVERT(VARCHAR, #DateTo, 121) + ''' BREAK
END'
EXEC sp_executesql #SQL
SELECT * FROM #DateRange
EDIT: Here's a modified version, not sure if this would be considered "better" but at least it eliminates the dynamic SQL, and I'm able to use it as a function.
EDIT2: since this runs quicker, I changed the limit to 5000 records returned. I also changed the direction it runs, so it starts from DateTo and works backwards. That way when it hits the limit, it just stops only going back so far. I also added some safety's, like checking the Increment (not sure what else to call it?) option values. I hate that giant case statement, but I don't see any other way to to do it.
CREATE FUNCTION dbo.uf_DateRange (
#DateFrom DATETIME,
#DateTo DATETIME,
#Increment VARCHAR(20)
)
RETURNS #Return TABLE (
BeginDate DATETIME,
EndDate DATETIME
)
AS
BEGIN
IF #Increment NOT IN ('year','yy','yyyy','quarter','qq','q','month','mm','m','week','wk','ww','day','dd','d','hour','hh','minute','mi','n','second','ss','s') RETURN
DECLARE #TargetDate DATETIME = #DateTo,
#LoopLimit INT = 5000,
#Counter INT = 0
DECLARE #DateRange TABLE (BeginDate DATETIME, EndDate DATETIME)
WHILE (#Counter < #LoopLimit)
BEGIN
INSERT INTO #Return (BeginDate, EndDate)
SELECT BeginDate = CASE WHEN #Increment IN ('year' , 'yy', 'yyyy') THEN DATEADD(yy, DATEDIFF(yy, 0, #TargetDate), 0)
WHEN #Increment IN ('quarter', 'qq', 'q' ) THEN DATEADD(qq, DATEDIFF(qq, 0, #TargetDate), 0)
WHEN #Increment IN ('month' , 'mm', 'm' ) THEN DATEADD(mm, DATEDIFF(mm, 0, #TargetDate), 0)
WHEN #Increment IN ('week' , 'wk', 'ww' ) THEN DATEADD(ww, DATEDIFF(ww, 0, #TargetDate), 0)
WHEN #Increment IN ('day' , 'dd', 'd' ) THEN DATEADD(dd, DATEDIFF(dd, 0, #TargetDate), 0)
WHEN #Increment IN ('hour' , 'hh' ) THEN DATEADD(hh, DATEDIFF(hh, 0, #TargetDate), 0)
WHEN #Increment IN ('minute' , 'mi', 'n' ) THEN DATEADD(mi, DATEDIFF(mi, 0, #TargetDate), 0)
WHEN #Increment IN ('second' , 'ss', 's' ) THEN DATEADD(ss, DATEDIFF(ss, 0, #TargetDate), 0)
END
, EndDate = DATEADD(ms, -3,
CASE WHEN #Increment IN ('year' , 'yy', 'yyyy') THEN DATEADD(yy, DATEDIFF(yy, 0, #TargetDate) + 1, 0)
WHEN #Increment IN ('quarter', 'qq', 'q' ) THEN DATEADD(qq, DATEDIFF(qq, 0, #TargetDate) + 1, 0)
WHEN #Increment IN ('month' , 'mm', 'm' ) THEN DATEADD(mm, DATEDIFF(mm, 0, #TargetDate) + 1, 0)
WHEN #Increment IN ('week' , 'wk', 'ww' ) THEN DATEADD(ww, DATEDIFF(ww, 0, #TargetDate) + 1, 0)
WHEN #Increment IN ('day' , 'dd', 'd' ) THEN DATEADD(dd, DATEDIFF(dd, 0, #TargetDate) + 1, 0)
WHEN #Increment IN ('hour' , 'hh' ) THEN DATEADD(hh, DATEDIFF(hh, 0, #TargetDate) + 1, 0)
WHEN #Increment IN ('minute' , 'mi', 'n' ) THEN DATEADD(mi, DATEDIFF(mi, 0, #TargetDate) + 1, 0)
WHEN #Increment IN ('second' , 'ss', 's' ) THEN DATEADD(ss, DATEDIFF(ss, 0, #TargetDate) + 1, 0)
END)
SET #TargetDate = CASE WHEN #Increment IN ('year' , 'yy', 'yyyy') THEN DATEADD(yy, -1, #TargetDate)
WHEN #Increment IN ('quarter', 'qq', 'q' ) THEN DATEADD(qq, -1, #TargetDate)
WHEN #Increment IN ('month' , 'mm', 'm' ) THEN DATEADD(mm, -1, #TargetDate)
WHEN #Increment IN ('week' , 'wk', 'ww' ) THEN DATEADD(ww, -1, #TargetDate)
WHEN #Increment IN ('day' , 'dd', 'd' ) THEN DATEADD(dd, -1, #TargetDate)
WHEN #Increment IN ('hour' , 'hh' ) THEN DATEADD(hh, -1, #TargetDate)
WHEN #Increment IN ('minute' , 'mi', 'n' ) THEN DATEADD(mi, -1, #TargetDate)
WHEN #Increment IN ('second' , 'ss', 's' ) THEN DATEADD(ss, -1, #TargetDate)
END
IF #TargetDate > #DateTo BREAK
SET #Counter += 1
END
RETURN
END
GO
You are going to run into a bunch of limitations here. It is my understanding that a function cannot execute a sproc so that is a big show-stopper. Also, you can't use a function to do an INSERT (or UPDATE or DELETE) so there's another big problem.
Is there a specific reason you can't leave it as a procedure?
1) I'm need only to pull data if the the openddate is equal to the PrevBiz date. I think the where/and statement would be Openddate = PrevBiz, but not sure. It wasn't working for me and could be because the date format isn't matching. Any Suggestions?
DECLARE #TODAY DATE = GETDATE()
DECLARE #PREVFIRST CHAR(8) = CONVERT(CHAR(8), DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 1, 0), 112)
DECLARE #PREVLAST CHAR(8) = CONVERT(CHAR(8), DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), -1), 112)
DECLARE #PREVBIZ CHAR(12) = DATEADD(DAY, CASE DATENAME(WEEKDAY, CONVERT(CHAR(12), #TODAY,112))
WHEN 'SUNDAY' THEN -2
WHEN 'MONDAY' THEN -3
ELSE -1 END, DATEDIFF(DAY, 0, CONVERT(CHAR(12), #TODAY, 112)))
SELECT TOP 10
CURRENTDATE =#TODAY,
FIRST_OF_MONTH =#PREVFIRST,
LASTDAY_OFMONTH =#PREVLAST,
PREVBIZ =#PREVBIZ,
DATEADD(DAY, CASE DATENAME(WEEKDAY, CONVERT(DATE, #TODAY,101))
WHEN 'SUNDAY' THEN -2
WHEN 'MONDAY' THEN -3
ELSE -1 END, DATEDIFF(DAY, 0, CONVERT(DATE, #TODAY, 101))) AS PREVIOUSBIZDATE,
OpendDate
FROM [USBI_DW].[USBI].[vw_NameAddressBase]
where IsCurrent = 1
Here's my results:
declare #TODAY datetime = convert(date,GETDATE())
declare #PREVBIZ datetime = DATEADD(DAY, CASE DATENAME(WEEKDAY,#TODAY)
WHEN 'SUNDAY' THEN -2
WHEN 'MONDAY' THEN -3
ELSE -1 END,#TODAY)
declare #iToday int = convert(nvarchar(8),#TODAY, 112)
, #iPrevBiz int = convert(nvarchar(8),#PREVBIZ, 112)
select top 10
CURRENTDATE =#iToday,
PREVBIZ =#iPrevBiz,
OpendDate
from [USBI_DW].[USBI].[vw_NameAddressBase]
where IsCurrent = 1
and OprendDate = #iPrevBiz
hope your view contains int date attribute ( because of DateWarehouse specific)
declare #start_date as datetime = '12/31/2014'
declare #end_date as datetime = '02/15/2015'
;with cte as (
select
datename(month,#start_date) as [mnth_nm],
month(#start_date) as [mnth_no],
#start_date as dat,
DATEADD(DAY, -1 * DAY(#start_date) + 1, #start_date) as [first_day],
DATEADD(dd, -DAY(DATEADD(mm, 1, #start_date)), DATEADD(mm, 1, #start_date)) as [last_day]
union all
select
datename(month, DateAdd(Month, 1, dat)),
month(dat) + 1 as [mnth_no],
DateAdd(Month, 1, dat),
DATEADD(MONTH, 1, [first_day]),
DATEADD(dd, -DAY(DATEADD(mm, 1, dat)),
DATEADD(mm, 1, dat)) + 1
from
cte
where
DateAdd(Month,1,dat) < #end_date
)
select
[mnth_nm], [mnth_no], #start_date, [first_day], [last_day]
from
CTE
In above CTE the required output should give december, january and february month output based on my start and end date.
Change the where query only:-
DateAdd(Month,0,dat)< #end_date
<b>Got the solution ... </b>
<p>
declare #start_date as datetime = '12/31/2014'
declare #end_date as datetime = '03/15/2015'
;with cte as (
select
datename(month,#start_date) as [mnth_nm],
month(#start_date) as [mnth_no],
#start_date as dat,
DATEADD(DAY, -1 * DAY(#start_date) + 1, #start_date) as [first_day],
DATEADD(dd, -DAY(DATEADD(mm, 1, #start_date)), DATEADD(mm, 1, #start_date)) as [last_day]
union All
select
datename(month, DateAdd(Month, 1, dat)),
month(DateAdd(m,1,dat)) as [mnth_no],
DateAdd(Month, 1, dat),
DATEADD(MONTH, 1, [first_day]),
DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, DATEADD(MONTH, 1, [first_day])) + 1, 0))
from
cte
where
DateAdd(Month,0,dat)< #end_date
)
select
[mnth_nm], [mnth_no], #start_date, [first_day], [last_day]
from
CTE</p>
IF OBJECT_ID('dbo.DimensionDate', 'U') IS NOT NULL
DROP TABLE dbo.DimensionDate
/**********************************************************************************/
CREATE TABLE [dbo].[DimensionDate]
( [DateKey] INT primary key,
[Date] DATETIME,
[FullDate] CHAR(10),-- Date in dd-MM-yyyy format
[DayOfMonth] VARCHAR(2), -- Field will hold day number of Month
[DaySuffix] VARCHAR(4), -- Apply suffix as 1st, 2nd ,3rd etc
[DayName] VARCHAR(9), -- Contains name of the day, Sunday, Monday
[DayOfWeekIRE] CHAR(1),-- First Day Monday=1 and Sunday=7
[DayOfWeekInMonth] VARCHAR(2), --1st Monday or 2nd Monday in Month
[DayOfWeekInYear] VARCHAR(2),
[DayOfQuarter] VARCHAR(3),
[DayOfYear] VARCHAR(3),
[WeekOfMonth] VARCHAR(1),-- Week Number of Month
[WeekOfQuarter] VARCHAR(2), --Week Number of the Quarter
[WeekOfYear] VARCHAR(2),--Week Number of the Year
[Month] VARCHAR(2), --Number of the Month 1 to 12
[MonthName] VARCHAR(9),--January, February etc
[MonthOfQuarter] VARCHAR(2),-- Month Number belongs to Quarter
[Quarter] CHAR(1),
[QuarterName] VARCHAR(9),--First,Second..
[Year] CHAR(4),-- Year value of Date stored in Row
[YearName] CHAR(7), --CY 2012,CY 2013
[MonthYear] CHAR(10), --Jan-2013,Feb-2013
[MMYYYY] CHAR(6),
[FirstDayOfMonth] DATE,
[LastDayOfMonth] DATE,
[FirstDayOfQuarter] DATE,
[LastDayOfQuarter] DATE,
[FirstDayOfYear] DATE,
[LastDayOfYear] DATE,
[IsHolidayIRE] BIT,-- Flag 1=National Holiday, 0-No National Holiday
[IsWeekday] BIT,-- 0=Week End ,1=Week Day
[HolidayIRE] VARCHAR(50),--Name of Holiday in US
[IsHolidayUK] BIT Null,-- Flag 1=National Holiday, 0-No National Holiday
[HolidayUK] VARCHAR(50) Null, --Name of Holiday in UK
[PastOrFuture] BIT Null -- Flag 0=Past, 1=Future
)
GO
TRUNCATE Table Dbo.DimensionDate
/********************************************************************************************/
--Specify Start Date and End date here
--Value of Start Date Must be Less than Your End Date
DECLARE #StartDate DATETIME = '04/01/2012' --Starting value of Date Range
DECLARE #EndDate DATETIME = '04/01/2015' --End Value of Date Range
--Temporary Variables To Hold the Values During Processing of Each Date of Year
DECLARE
#DayOfWeekInMonth INT,
#DayOfWeekInYear INT,
#DayOfQuarter INT,
#WeekOfMonth INT,
#CurrentYear INT,
#CurrentMonth INT,
#CurrentQuarter INT
/*Table Data type to store the day of week count for the month and year*/
DECLARE #DayOfWeek TABLE (DOW INT, MonthCount INT, QuarterCount INT, YearCount INT)
INSERT INTO #DayOfWeek VALUES (1, 0, 0, 0)
INSERT INTO #DayOfWeek VALUES (2, 0, 0, 0)
INSERT INTO #DayOfWeek VALUES (3, 0, 0, 0)
INSERT INTO #DayOfWeek VALUES (4, 0, 0, 0)
INSERT INTO #DayOfWeek VALUES (5, 0, 0, 0)
INSERT INTO #DayOfWeek VALUES (6, 0, 0, 0)
INSERT INTO #DayOfWeek VALUES (7, 0, 0, 0)
--Extract and assign various parts of Values from Current Date to Variable
DECLARE #CurrentDate AS DATETIME = #StartDate
SET #CurrentMonth = DATEPART(MM, #CurrentDate)
SET #CurrentYear = DATEPART(YY, #CurrentDate)
SET #CurrentQuarter = DATEPART(QQ, #CurrentDate)
SET #startDate = GETDATE()
/********************************************************************************************/
--Proceed only if Start Date(Current date ) is less than End date you specified above
WHILE #CurrentDate < #EndDate
BEGIN
/*Begin day of week logic*/
/*Check for Change in Month of the Current date if Month changed then
Change variable value*/
IF #CurrentMonth != DATEPART(MM, #CurrentDate)
BEGIN
UPDATE #DayOfWeek
SET MonthCount = 0
SET #CurrentMonth = DATEPART(MM, #CurrentDate)
END
/* Check for Change in Quarter of the Current date if Quarter changed then change
Variable value*/
IF #CurrentQuarter != DATEPART(QQ, #CurrentDate)
BEGIN
UPDATE #DayOfWeek
SET QuarterCount = 0
SET #CurrentQuarter = DATEPART(QQ, #CurrentDate)
END
/* Check for Change in Year of the Current date if Year changed then change
Variable value*/
IF #CurrentYear != DATEPART(YY, #CurrentDate)
BEGIN
UPDATE #DayOfWeek
SET YearCount = 0
SET #CurrentYear = DATEPART(YY, #CurrentDate)
END
-- Set values in table data type created above from variables
UPDATE #DayOfWeek
SET
MonthCount = MonthCount + 1,
QuarterCount = QuarterCount + 1,
YearCount = YearCount + 1
WHERE DOW = DATEPART(DW, #CurrentDate)
SELECT
#DayOfWeekInMonth = MonthCount,
#DayOfQuarter = QuarterCount,
#DayOfWeekInYear = YearCount
FROM #DayOfWeek
WHERE DOW = DATEPART(DW, #CurrentDate)
/End day of week logic/
/* Populate Your Dimension Table with values*/
INSERT INTO [dbo].[DimensionDate]
SELECT
CONVERT (char(8),#CurrentDate,112) as DateKey,
#CurrentDate AS Date,
CONVERT (char(10),#CurrentDate,103) as FullDate,
DATEPART(DD, #CurrentDate) AS DayOfMonth,
--Apply Suffix values like 1st, 2nd 3rd etc..
CASE
WHEN DATEPART(DD,#CurrentDate) IN (11,12,13)
THEN CAST(DATEPART(DD,#CurrentDate) AS VARCHAR) + 'th'
WHEN RIGHT(DATEPART(DD,#CurrentDate),1) = 1
THEN CAST(DATEPART(DD,#CurrentDate) AS VARCHAR) + 'st'
WHEN RIGHT(DATEPART(DD,#CurrentDate),1) = 2
THEN CAST(DATEPART(DD,#CurrentDate) AS VARCHAR) + 'nd'
WHEN RIGHT(DATEPART(DD,#CurrentDate),1) = 3
THEN CAST(DATEPART(DD,#CurrentDate) AS VARCHAR) + 'rd'
ELSE CAST(DATEPART(DD,#CurrentDate) AS VARCHAR) + 'th'
END AS DaySuffix,
DATENAME(DW, #CurrentDate) AS DayName,
-- check for day of week as Per US and change it as per UK format
CASE DATEPART(DW, #CurrentDate)
WHEN 1 THEN 7
WHEN 2 THEN 1
WHEN 3 THEN 2
WHEN 4 THEN 3
WHEN 5 THEN 4
WHEN 6 THEN 5
WHEN 7 THEN 6
END
AS DayOfWeekIRE,
#DayOfWeekInMonth AS DayOfWeekInMonth,
#DayOfWeekInYear AS DayOfWeekInYear,
#DayOfQuarter AS DayOfQuarter,
DATEPART(DY, #CurrentDate) AS DayOfYear,
DATEPART(WW, #CurrentDate) + 1 - DATEPART(WW, CONVERT(VARCHAR,
DATEPART(MM, #CurrentDate)) + '/1/' + CONVERT(VARCHAR,
DATEPART(YY, #CurrentDate))) AS WeekOfMonth,
(DATEDIFF(DD, DATEADD(QQ, DATEDIFF(QQ, 0, #CurrentDate), 0),
#CurrentDate) / 7) + 1 AS WeekOfQuarter,
DATEPART(WW, #CurrentDate) AS WeekOfYear,
DATEPART(MM, #CurrentDate) AS Month,
DATENAME(MM, #CurrentDate) AS MonthName,
CASE
WHEN DATEPART(MM, #CurrentDate) IN (1, 4, 7, 10) THEN 1
WHEN DATEPART(MM, #CurrentDate) IN (2, 5, 8, 11) THEN 2
WHEN DATEPART(MM, #CurrentDate) IN (3, 6, 9, 12) THEN 3
END AS MonthOfQuarter,
DATEPART(QQ, #CurrentDate) AS Quarter,
CASE DATEPART(QQ, #CurrentDate)
WHEN 1 THEN 'First'
WHEN 2 THEN 'Second'
WHEN 3 THEN 'Third'
WHEN 4 THEN 'Fourth'
END AS QuarterName,
DATEPART(YEAR, #CurrentDate) AS Year,
'CY ' + CONVERT(VARCHAR, DATEPART(YEAR, #CurrentDate)) AS YearName,
LEFT(DATENAME(MM, #CurrentDate), 3) + '-' + CONVERT(VARCHAR,
DATEPART(YY, #CurrentDate)) AS MonthYear,
RIGHT('0' + CONVERT(VARCHAR, DATEPART(MM, #CurrentDate)),2) +
CONVERT(VARCHAR, DATEPART(YY, #CurrentDate)) AS MMYYYY,
CONVERT(DATETIME, CONVERT(DATE, DATEADD(DD, - (DATEPART(DD,
#CurrentDate) - 1), #CurrentDate))) AS FirstDayOfMonth,
CONVERT(DATETIME, CONVERT(DATE, DATEADD(DD, - (DATEPART(DD,
(DATEADD(MM, 1, #CurrentDate)))), DATEADD(MM, 1,
#CurrentDate)))) AS LastDayOfMonth,
DATEADD(QQ, DATEDIFF(QQ, 0, #CurrentDate), 0) AS FirstDayOfQuarter,
DATEADD(QQ, DATEDIFF(QQ, -1, #CurrentDate), -1) AS LastDayOfQuarter,
CONVERT(DATETIME, '01/01/' + CONVERT(VARCHAR, DATEPART(YY,
#CurrentDate))) AS FirstDayOfYear,
CONVERT(DATETIME, '12/31/' + CONVERT(VARCHAR, DATEPART(YY,
#CurrentDate))) AS LastDayOfYear,
NULL AS IsHolidayIRE,
CASE DATEPART(DW, #CurrentDate)
WHEN 1 THEN 0
WHEN 2 THEN 1
WHEN 3 THEN 1
WHEN 4 THEN 1
WHEN 5 THEN 1
WHEN 6 THEN 1
WHEN 7 THEN 0
END AS IsWeekday,
NULL AS HolidayIRE, Null, Null
UPDATE
DimensionDate
SET [PastOrFuture] =
CASE
WHEN #StartDate <= [DATE] THEN 0
ELSE 1
END
SET #CurrentDate = DATEADD(DD, 1, #CurrentDate)
END
SELECT * FROM DimensionDate
Msg 213, Level 16, State 1, Line 99 Column name or number of supplied values does not match table definition.
I just want to fix the update in at the bottom of this code its not letting me update PastOrFuture Column to 0 or 1 depending on the date
It works perfect if i take out my update and put back in the null.
Try removing your update statement and replace the following code at the and check?
.... NULL AS HolidayIRE, Null, Null,
CASE
WHEN #StartDate <= [DATE] THEN 0
ELSE 1
END
FROM DimensionDate
I think you are trying to update in insert. You can calculate past of future in the select statement itself
Your INSERT into DimensionDate is short a column.
You have 3 columns after HolidayIRE, but your insert only has 2 NULLS after the case for HolidayIRE
Either add a column list to the insert, or add another NULL to the end of the insert.
For that matter, no need to UPDATE just tack your case on the end of the INSERT and make the case the last column and insert the PastOrFuture on the fly...
CASE
WHEN #StartDate <= [DATE] THEN 0
ELSE 1
END
You did not supply pastorfuture, count your fields vs the table. you have HolidayIRE, null, null and the table reads HolidayIRE, IsHolidayUK, HolidayUK, PastOrFuture
Ex: date range is 01-01-2011 to 01-01-2012, I want the output like this :
01-01-2011 31-01-2011
01-02-2011 28-02-2011
How can I do this ? I'm using SQL Server 2005..
Thanks
Using CTE:
DECLARE #Begin DATETIME
DECLARE #End DATETIME
SELECT #Begin = '20110101', #End = '20120101'
;WITH ranges(DateFrom, DateTo) AS
(
SELECT #Begin, DATEADD(DAY, -1, DATEADD(MONTH, 1, #begin))
UNION ALL
SELECT DATEADD(month, 1, DateFrom), DATEADD(DAY, -1, DATEADD(MONTH, 2, DateFrom))
FROM ranges
WHERE DateFrom < #End
)
SELECT * FROM ranges
OPTION(MAXRECURSION 0)
And not using CTE:
DECLARE #Begin DATETIME
DECLARE #End DATETIME
SELECT #Begin = '20110101', #End = '20120101'
SELECT DATEADD(MONTH, n.Number, #Begin) DateFrom, DATEADD(day, -1, DATEADD(MONTH, n.Number+1, #Begin)) DateTo
FROM master.dbo.spt_values n
WHERE
n.Number < DATEDIFF(MONTH, #begin, #end)
AND n.Type = 'P'
If you need to include January 2012 too, use this
DECLARE #Begin DATETIME
DECLARE #End DATETIME
SELECT #Begin = '20110101', #End = '20120101'
SELECT DATEADD(MONTH, n.Number, #Begin) DateFrom, DATEADD(day, -1, DATEADD(MONTH, n.Number+1, #Begin)) DateTo
FROM master.dbo.spt_values n
WHERE
n.Number <= DATEDIFF(MONTH, #begin, #end)
AND n.Type = 'P'
And CTE:
DECLARE #Begin DATETIME
DECLARE #End DATETIME
SELECT #Begin = '20110101', #End = '20120101'
;WITH ranges(DateFrom, DateTo) AS
(
SELECT #Begin, DATEADD(DAY, -1, DATEADD(MONTH, 1, #begin))
UNION ALL
SELECT DATEADD(month, 1, DateFrom), DATEADD(DAY, -1, DATEADD(MONTH, 2, DateFrom))
FROM ranges
WHERE DATEADD(month, 1, DateFrom) < #End
)
SELECT * FROM ranges
OPTION(MAXRECURSION 0)
>On Providing the Start and End Date range, it can be split into months. This might help.
DECLARE #StartDate datetime
DECLARE #EndDate datetime
DECLARE #tmpStart datetime
DECLARE #tmpEnd datetime
Select #StartDate = '2012-01-01'
Select #EndDate = '2009-01-01'
Select #StartDate = DATEADD(MONTH,1,Convert(DATETIME,Convert(VARCHAR(25), Datepart (YEAR,#StartDate)) + '-' + Convert(VARCHAR(25), Datepart(MONTH, #StartDate)) + '-' + Convert(VARCHAR(25), 1)))
Select #EndDate = DATEADD(MONTH,1,Convert(DATETIME,Convert(VARCHAR(25), Datepart(YEAR, #EndDate)) + '-' + Convert(VARCHAR(25), Datepart(MONTH, #EndDate)) + '-' + Convert(VARCHAR(25), 1)))
Select #EndDate = DATEADD(DD,-1, DATEADD(MM,1,#EndDate))
Select #tmpEnd = #EndDate
Select #tmpStart = Convert(DATETIME,Convert(VARCHAR(25), Datepart(YEAR, #tmpEnd)) + '-' +
Convert(VARCHAR(25), Datepart(MONTH, #tmpEnd)) + '-' + Convert(VARCHAR(25), 1))
Select #StartDate 'Start' , #EndDate 'End'
While #tmpStart <= #StartDate
BEGIN
Select #tmpStart 'tmpStart' , #tmpEnd 'tmpEnd'
Select #tmpStart = DATEADD(MM,1,#tmpStart)
Select #tmpEnd = DATEADD(DD,-1,DATEADD (MM, 1 , #tmpStart))
END