I am trying to create a query that yields Year, Iso week and sum of amount for that year and week.
My problem is that the way I am doing it returns the amount for the first days of 2021 as being from week 53 when it actually should of course be a part of week 53 of the year 2020.
Here is my query:
SELECT
datepart(year, [MyDate]) AS [Year],
datepart(iso_week,[MyDate]) AS WeekNumber,
sum([Amount]) AS TotalAmount
FROM [Temp].[dbo].[MyTable]
GROUP BY datepart(year, [MyDate]), datepart(iso_week,[MyDate])
ORDER BY datepart(year, [MyDate]), datepart(iso_week,[MyDate])
How can this be fixed?
Sadly, SQL Server offers iso_week as an argument to datepart(), but not iso_year. Some perusing on the web suggests this code:
SELECT v.iso_year, v.iso_week,
sum([Amount]) AS TotalAmount
FROM [Temp].[dbo].[MyTable] t CROSS APPLY
(VALUES (YEAR(DATEADD(day, 26 - DATEPART(isoww, DATEFROMPARTS(YEAR(t.mydate), 1, 1)), DATEFROMPARTS(YEAR(t.mydate), 1, 1))),
datepart(iso_week, t.[MyDate])
)
) v(iso_year, iso_week)
GROUP BY iso_year, iso_week
ORDER BY iso_year, iso_week
I found a solution by doing this:
SELECT
dbo.GetIsoYear(MyDate) AS [Year],
datepart(iso_week,MyDate) AS WeekNumber,
sum(Amount) AS 'TotalAmount'
FROM MyTable
GROUP BY dbo.GetIsoYear(MyDate), datepart(iso_week,MyDate)
ORDER BY dbo.GetIsoYear(MyDate), datepart(iso_week,MyDate)
and here is the function I am using:
ALTER FUNCTION [dbo].[GetIsoYear](#Date datetime)
RETURNS int
AS
BEGIN
DECLARE #ResultVar int
DECLARE #IsoWeek int
DECLARE #Month int
SELECT #IsoWeek = DATEPART(ISO_WEEK,#Date)
SELECT #Month = DATEPART(MONTH,#Date)
IF #IsoWeek = 53 AND #Month = 1
SET #ResultVar = YEAR(#Date) - 1
ELSE
SET #ResultVar = YEAR(#Date)
RETURN #ResultVar
END
I do not know if using a function here has performance issues but I would think that it should run rather fast.
I am trying to get the fiscal period and year out of an invoice date. Using the month() function together with the Case I am able to get the period. since Period 1 is in November I need to do a +1 1 the year when this is true
Using the IF function together with the date functions are now working for me.
My query is
Select a.OrderAccount
,a.InvoiceAccount
,a.InvoiceDate
,year(a.InvoiceDate) as Year
,month(a.InvoiceDate) as Month,
Case month(a.InvoiceDate)
WHEN '11' THEN '1' -- increase year by +1
WHEN '12' THEN '2'-- increase year by +1
WHEN '1' THEN '3'
WHEN '2' THEN '4'
WHEN '3' THEN '5'
Any advice would be appreciated. Thanks
Use DATEADD to just add 2 months to the original date:
MONTH(DATEADD(month,2,a.InvoiceDate)) as FiscalMonth,
YEAR(DATEADD(month,2,a.InvoiceDate)) AS FiscalYear,
Create and populate a Calendar Table (it makes working with dates much easier).
create table Calendar
(
id int primary key identity,
[date] datetime,
[day] as datepart(day, [date]) persisted,
[month] as datepart(month, [date]) persisted,
[year] as datepart(year, [date]) persisted,
day_of_year as datepart(dayofyear, [date]) persisted,
[week] as datepart(week, [date]),
day_name as datename(dw, [date]),
is_weekend as case when datepart(dw, [date]) = 7 or datepart(dw, [date]) = 1 then 1 else 0 end,
[quarter] as datepart(quarter, [date]) persisted
--etc...
)
--populate the calendar
declare #date datetime
set #date = '1-1-2000'
while #date <= '12-31-2100'
begin
insert Calendar select #date
set #date = dateadd(day, 1, #date)
end
Then, create a FiscalYear view:
create view FiscalYear
as
select
id,
case when month = 11 or month = 12 then year + 1 else year end as [year]
from Calendar
So, whenever you need the fiscal year of a given date, just use something like the following query:
select C.*, FY.year fiscal_year from Calendar C inner join FiscalYear FY on FY.id = C.id
Of course, since fiscal year is just a computation on a column, you could also just make it a part of the calendar table itself. Then, it's simply:
select * from Calendar
If you want to stick with arithmetic: The fiscal month is ( Month( a.InvoiceDate ) + 1 ) % 12 + 1 and the value to add to the calendar year to get the fiscal year is Month( a.InvoiceDate ) / 11.
The following code demonstrates 12 months:
with Months as (
select 1 as M
union all
select M + 1
from Months
where M < 12 )
select M, ( M + 1 ) % 12 + 1 as FM, M / 11 as FYOffset
from Months;
D Stanley's answer makes your intention clearer, always a consideration for maintainability.
If you have this logic in 10 different places and the logic changes starting (say) on 1/1/2018 you will have a mess on your hands.
Create a function that has the logic and then use the function like:
SELECT InvoiceDate, dbo.FiscalPeriod(InvoiceDate) AS FP
FROM ...
Something like:
CREATE FUNCTION dbo.FiscalPeriod(#InvoiceDate DateTime)
RETURNS int
AS BEGIN
DECLARE #FiscalDate DateTime
SET #FiscalDate = DATEADD(month, 2, #InvoiceDate)
RETURN YEAR(#FiscalDate) * 100 + MONTH(#FiscalDate)
END
This returns values like 201705, but you could have dbo.FiscalPeriodMonth() and dbo.FiscalPeriodYear() if you needed. And you can have as complicated logic as you need in one place.
I have months stored in SQL Server as 1,2,3,4,...12. I would like to display them as January,February etc. Is there a function in SQL Server like MonthName(1) = January? I am trying to avoid a CASE statement, if possible.
I think this is the best way to get the month name when you have the month number
Select DateName( month , DateAdd( month , #MonthNumber , 0 ) - 1 )
Or
Select DateName( month , DateAdd( month , #MonthNumber , -1 ) )
A little hacky but should work:
SELECT DATENAME(month, DATEADD(month, #mydate-1, CAST('2008-01-01' AS datetime)))
SELECT DATENAME(month, GETDATE()) AS 'Month Name'
SUBSTRING('JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC ', (#intMonth * 4) - 3, 3)
Use the Best way
Select DateName( month , DateAdd( month , #MonthNumber , -1 ))
It is very simple.
select DATENAME(month, getdate())
output : January
Starting with SQL Server 2012, you can use FORMAT and DATEFROMPARTS to solve this problem. (If you want month names from other cultures, change: en-US)
select FORMAT(DATEFROMPARTS(1900, #month_num, 1), 'MMMM', 'en-US')
If you want a three-letter month:
select FORMAT(DATEFROMPARTS(1900, #month_num, 1), 'MMM', 'en-US')
If you really want to, you can create a function for this:
CREATE FUNCTION fn_month_num_to_name
(
#month_num tinyint
)
RETURNS varchar(20)
AS
BEGIN
RETURN FORMAT(DATEFROMPARTS(1900, #month_num, 1), 'MMMM', 'en-US')
END
You can use the inbuilt CONVERT function
select CONVERT(varchar(3), Date, 100) as Month from MyTable.
This will display first 3 characters of month (JAN,FEB etc..)
in addition to original
SELECT DATENAME(m, str(2) + '/1/2011')
you can do this
SELECT DATENAME(m, str([column_name]) + '/1/2011')
this way you get names for all rows in a table. where [column_name] represents a integer column containing numeric value 1 through 12
2 represents any integer, by contact string i created a date where i can extract the month. '/1/2011' can be any date
if you want to do this with variable
DECLARE #integer int;
SET #integer = 6;
SELECT DATENAME(m, str(#integer) + '/1/2011')
In some locales like Hebrew, there are leap months dependant upon the year so to avoid errors in such locales you might consider the following solution:
SELECT DATENAME(month, STR(YEAR(GETDATE()), 4) + REPLACE(STR(#month, 2), ' ', '0') + '01')
The following works for me:
CAST(GETDATE() AS CHAR(3))
Use this statement to convert Month numeric value to Month name.
SELECT CONVERT(CHAR(3), DATENAME(MONTH, GETDATE()))
Just subtract the current month from today's date, then add back your month number. Then use the datename function to give the full name all in 1 line.
print datename(month,dateadd(month,-month(getdate()) + 9,getdate()))
Sure this will work
select datename(M,GETDATE())
SELECT DateName(M, DateAdd(M, #MONTHNUMBER, -1))
To convert month number to month name, try the below
declare #month smallint = 1
select DateName(mm,DATEADD(mm,#month - 1,0))
You can use the convert functin as below
CONVERT(VARCHAR(3), DATENAME(MM, GETDATE()), 100)
i think this is enough to get month name when u have date.
SELECT DATENAME(month ,GETDATE())
SELECT DATENAME(MONTH,dateadd(month, -3,getdate()))
This one worked for me:
#MetricMonthNumber (some number)
SELECT
(DateName( month , DateAdd( month , #MetricMonthNumber - 1 , '1900-01-01' ) )) AS MetricMonthName
FROM TableName
From a post above from #leoinfo and #Valentino Vranken. Just did a quick select and it works.
Declare #MonthNumber int
SET #MonthNumber=DatePart(Month,GETDATE())
Select DateName( month , DateAdd( month , #MonthNumber , 0 ) - 1 )
Explaination:
First Decalre Variable MonthNumber
Get Current Month for DatePart which Return Month Number
Third Query Return Month Name
select monthname(curdate());
OR
select monthname('2013-12-12');
Working for me
SELECT MONTHNAME(<fieldname>) AS "Month Name" FROM <tablename> WHERE <condition>
you can get the date like this.
eg:- Users table
id name created_at
1 abc 2017-09-16
2 xyz 2017-06-10
you can get the monthname like this
select year(created_at), monthname(created_at) from users;
output
+-----------+-------------------------------+
| year(created_at) | monthname(created_at) |
+-----------+-------------------------------+
| 2017 | september |
| 2017 | june |
You can create a function like this to generate the Month and do
SELECT dbo.fn_GetMonthFromDate(date_column) as Month FROM table_name
/****** Object: UserDefinedFunction [dbo].[fn_GetMonthFromDate] Script Date: 11/16/2018 10:26:33 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[fn_GetMonthFromDate]
(#date datetime)
RETURNS varchar(50)
AS
BEGIN
DECLARE #monthPart int
SET #monthPart = MONTH(#date)
IF #monthPart = 1
BEGIN
RETURN 'January'
END
ELSE IF #monthPart = 2
BEGIN
RETURN 'February'
END
ELSE IF #monthPart = 3
BEGIN
RETURN 'March'
END
ELSE IF #monthPart = 4
BEGIN
RETURN 'April'
END
ELSE IF #monthPart = 5
BEGIN
RETURN 'May'
END
ELSE IF #monthPart = 6
BEGIN
RETURN 'June'
END
ELSE IF #monthPart = 7
BEGIN
RETURN 'July'
END
ELSE IF #monthPart = 8
BEGIN
RETURN 'August'
END
ELSE IF #monthPart = 9
BEGIN
RETURN 'September'
END
ELSE IF #monthPart = 10
BEGIN
RETURN 'October'
END
ELSE IF #monthPart = 11
BEGIN
RETURN 'November'
END
ELSE IF #monthPart = 12
BEGIN
RETURN 'December'
END
RETURN NULL END
Here is my solution using some information from others to solve a problem.
datename(month,dateadd(month,datepart(month,Help_HelpMain.Ticket_Closed_Date),-1)) as monthname
There is no system defined function in SQL server. But you can create your own user-defined function- a scalar function. You would find scalar functions in the Object Explorer for your database: Programmability->Functions->Scalar-valued Functions. Below, I use a table variable to bring it all together.
--Create the user-defined function
CREATE FUNCTION getmonth (#num int)
RETURNS varchar(9) --since 'September' is the longest string, length 9
AS
BEGIN
DECLARE #intMonth Table (num int PRIMARY KEY IDENTITY(1,1), month varchar(9))
INSERT INTO #intMonth VALUES ('January'), ('February'), ('March'), ('April'), ('May')
, ('June'), ('July'), ('August') ,('September'), ('October')
, ('November'), ('December')
RETURN (SELECT I.month
FROM #intMonth I
WHERE I.num = #num)
END
GO
--Use the function for various months
SELECT dbo.getmonth(4) AS [Month]
SELECT dbo.getmonth(5) AS [Month]
SELECT dbo.getmonth(6) AS [Month]
to_char(to_date(V_MONTH_NUM,'MM'),'MONTH')
where V_MONTH_NUM is the month number
SELECT to_char(to_date(V_MONTH_NUM,'MM'),'MONTH') from dual;
Use this statement for getting month name:
DECLARE #date datetime
SET #date='2015/1/4 00:00:00'
SELECT CAST(DATENAME(month,#date ) AS CHAR(3))AS 'Month Name'
This will give you short month name. Like this: Jan, Feb, Mar, etc.
Try this: SELECT MONTHNAME(concat('1970-',[Month int val],'-01'))
For example- SELECT MONTHNAME(concat('1970-',4,'-01'))
The answer is - April