SQL Date Help Needed - sql

I have the following query
-- DELETE Current month and Month - 1 records from MonthlyTbl
DELETE FROM dbo.tbl_SDW_MONTHLY_AS
WHERE [Month Number] > MONTH(GETDATE()) - 2
AND [Year] = YEAR(GETDATE())
The query does not appear to be deleting the records from December 2013, can you help me fix this?

You can do it this way.
declare #dt datetime
set #dt = getdate()
DELETE FROM dbo.tbl_SDW_MONTHLY_AS
WHERE
100 * [Year] + [Month Number] >=
(
100 * datepart(YEAR, dateadd(DAY, - datepart(DAY, #dt) - 1, #dt)) +
datepart(MONTH, dateadd(DAY, - datepart(DAY, #dt) - 1, #dt))
)

Don't use MONTH number and YEAR number.
Use the dates instead.
DELETE FROM dbo.tbl_SDW_MONTHLY_AS
WHERE [Date] > DATEADD(MONTH,-2,GETDATE())

Related

SQL Date Logic Clause

Having problems understanding how to get the Where clause to work with this date structure.
Here is the principal logic. I want data only from previous March 1 onward and ending on yesterdays date.
Example #1:
So today is Feb 13, 2015 This would mean I need data between (2014-03-01 and 2015-02-12)
Example #2:
Say today is March 20, 2015 This This would mean I need data between (2015-03-01 and 2015-03-19)
The where logic might work but it doesn't like to convert '3/1/' + year. But I'm not sure how else to express it. The first clause is fine its the Case section that is broken.
Query
SELECT [Request Date], [myItem]
FROM myTable
WHERE [Request Date] < CONVERT(VARCHAR(10), GETDATE(), 102)
AND [Request Date] = CASE WHEN
CONVERT(VARCHAR(10), GETDATE(), 102) <
CONVERT(VARCHAR(12), '3/1/' + DATEPART ( year , GETDATE()) , 114)
THEN [Request Date] > CONVERT(VARCHAR(12), '3/1/' + DATEPART ( year , GETDATE()-365) , 114)
ELSE [Request Date] > CONVERT(VARCHAR(12), '3/1/' + DATEPART ( year , GETDATE() , 114)
END
I have also tried
AND [Request Date] = CASE WHEN
CONVERT(VARCHAR(10), GETDATE(), 102) <
'3/1/' + CONVERT(VARCHAR(12), DATEPART ( YYYY , GETDATE()))
THEN [Request Date] > '3/1/' + CONVERT(VARCHAR(12), DATEPART ( YYYY , GETDATE()-364))
ELSE [Request Date] > '3/1/' + CONVERT(VARCHAR(12), DATEPART ( YYYY , GETDATE()))
END
Try this where clause.
WHERE [Request Date]
BETWEEN Cast(CONVERT(VARCHAR(4), Year(Getdate())-1)+ '-03-01' AS DATE)
AND Getdate() - 1
Here Cast(CONVERT(VARCHAR(4), Year(Getdate())-1)+ '-03-01' AS DATE) will fetch the first day of march month. With that add -1 year to get the starting point.
Getdate() - 1 will define the ending point
I'd prefer to create datetime variables for the #from - #to range but if this is for a view I guess you have to do it in the where clause.
SELECT [Request Date], [myItem]
FROM myTable
WHERE [Request Date] < cast(GETDATE() as date)
AND [Request Date] >= CASE WHEN
GETDATE() < CONVERT(datetime, '3/1/' + cast(Year(GETDATE()) as varchar(4)))
THEN CONVERT(datetime, '3/1/' + cast(Year(GETDATE()) - 1 as varchar(4)))
ELSE CONVERT(datetime, '3/1/' + cast(Year(GETDATE()) as varchar(4)))
END
Something like this? Always from Mar 1st onwards, previous year if it's now Mar 1 or earlier, and otherwise this year.
SELECT [Request Date], [myItem]
FROM myTable
WHERE [Request Date] >= dateadd(month, 2, DATEADD(year, DATEDIFF(year, 0, dateadd(month, -2, dateadd(day, -1, getdate()))), 0))
and [Request Date] < DATEADD(day, DATEDIFF(day, 0, getdate()), 0)
First it deducts one day, so that March 1 isn't taking the same year, then it deducts 2 months for getting those dates for previous year, then it rounds it to the year, and then it adds 2 months to get to Mar 1.
In Oracle, I'd compute the lower bound like this:
add_months( trunc( add_months( sysdate, -2 ), 'YEAR'), 2 )
In other words - subtract two months, round down to the start of the year, then add two months.
Hopefully, you can convert this to use appropriate TSQL functions.
Lets work with some test data:
DECLARE #MyDate DATETIME = '3/13/2015'
Going to declare some variable we will set:
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
In this code, I check to see if we are before or after march 1st, and if so we will use either the previous year, or this year for the starting point (fiscal year?)
SELECT #StartDate = CASE WHEN DATEPART(MONTH, #MyDate) < 3 THEN
DATEADD(MONTH, 2, DATEADD(YEAR, DATEDIFF(YEAR, 0, #MyDate) - 1, 0))
ELSE
DATEADD(MONTH, 2, DATEADD(YEAR, DATEDIFF(YEAR, 0, #MyDate), 0))
END,
#EndDate = DATEADD(DAY, DATEDIFF(DAY, 0, #MyDate), 0)
Here is the output:
SELECT #StartDate AS Start, #EndDate AS EndDate
Start EndDate
2015-03-01 00:00:00.000 2015-03-13 00:00:00.000
I would first create a fairly generic user-defined function that does what I need, thus:
create function dbo.start_of_fiscal_year
(
#today date ,
#fiscal_year_start_month int
)
returns date
as
begin
set #today = case coalesce(#today,'')
when '' then current_timestamp
else #today
end
declare #month_start date = dateadd(day,1-datepart(day,#today),#today)
declare #fiscal_month_number int = case sign( datepart(month,#month_start) - #fiscal_year_start_month )
when -1 then 13
else 1
end
+ ( datepart(month,#month_start) - #fiscal_year_start_month )
declare #fiscal_year_start date = dateadd(month,1-#fiscal_month_number,#month_start)
return #fiscal_year_start
end
go
Once you have that you can say things like
declare #today date = current_timetamp
declare #fy_start date = start_of_fiscal_year(#today,3)
select *
from dbo.foo t
where t.report_date >= #fy_start
and t.report_date < #today
or even
select fiscal_year = datepart(year,start_of_fiscal_year(t.report_date,3)) , count(*)
from dbo.foo t
group by datepart(year,start_of_fiscal_year(t.report_date,3))
Your lower bound should be this. You just need to offset the year when month is less than 3 (March).
dateadd(
yy,
year(current_timestamp) - 1900 + case when month(current_timestamp) < 3 then -1 else 0 end,
'19000301'
)
There's no reason to mess around with strings and this consolidates the logic very concisely. I'm also guessing that when current date is March 1 that you want to query the full previous year. So you'll want to adjust the test slightly.
case when (month(dateadd(dd, -1, current_timestamp)) < 3 ...
And just for fun:
dateadd(mm, (12-month(current_timestamp-1))/10*-12+2, cast(year(current_timestamp) as char(4)));

How to get this condition in where clause of Sql

I have a query which gives me the last month's completed data
select * from Tabl
where datepart(month, completed_date) = DATEPART(month, getDate())-1
and datepart(year, completed_date) = datepart(year, getDate())
But it gives me wrong data when the current date is in january
How can I write the condition to return correct data if the current month is January?
SQL Server's DATEADD function will help you here.
select * from Tabl
where datepart(month, completed_date) = DATEPART(month, DATEADD(MM,-1,getDate()))
and datepart(year, completed_date) = datepart(year, DATEADD(MM,-1,getDate()))
The 'MM' used is just a keyword for Month.
Well, try subtracting one month from the date instead:
select *
from Tabl
where month(completed_date) = month(dateadd(month, -1, getdate()) and
year(completed_date) = year(dateadd(month, -1, getdate());
But, if you have an index on completed_date, it is better to put all the operations on getdate() so the expression is "sargable" (that is, an index can be used):
where completed_date >= cast(dateadd(month, -1, getdate() - day(getdate() + 1) as date) and
completed_date < cast(getdate() - day(getdate())
When you subtract the "day of the month" from the date, you get the last day of the previous month.
select * from Tabl
where
datepart(year, completed_date) * 100 + datepart(month, completed_date)
<
datepart(year, getDate()) * 100 + datepart(month, GetDate())

Group days by week

Is there is a way to group dates by week of month in SQL Server?
For example
Week 2: 05/07/2012 - 05/13/2012
Week 3: 05/14/2012 - 05/20/2012
but with Sql server statement
I tried
SELECT SOMETHING,
datediff(wk, convert(varchar(6), getdate(), 112) + '01', getdate()) + 1 AS TIME_
FROM STATISTICS_
GROUP BY something, TIME_
ORDER BY TIME_
but it returns the week number of month. (means 3)
How to get the pair of days for current week ?
For example, now we are in third (3rd) week and I want to show 05/14/2012 - 05/20/2012
I solved somehow:
SELECT DATEADD(ww, DATEDIFF(ww,0,<my_column_name>), 0)
select DATEADD(ww, DATEDIFF(ww,0,<my_column_name>), 0)+6
Then I will get two days and I will concatenate them later.
All right, bear with me here. We're going to build a temporary calendar table that represents this month, including the days from before and after the month that fall into your definition of a week (Monday - Sunday). I do this in a lot of steps to try to make the process clear, but I probably haven't excelled at that in this case.
We can then generate the ranges for the different weeks, and you can join against your other tables using that.
SET DATEFIRST 7;
SET NOCOUNT ON;
DECLARE #today SMALLDATETIME, #fd SMALLDATETIME, #rc INT;
SELECT #today = DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0), -- today
#fd = DATEADD(DAY, 1-DAY(#today), #today), -- first day of this month
#rc = DATEPART(DAY, DATEADD(DAY, -1, DATEADD(MONTH, 1, #fd)));-- days in month
DECLARE #thismonth TABLE (
[date] SMALLDATETIME,
[weekday] TINYINT,
[weeknumber] TINYINT
);
;WITH n(d) AS (
SELECT TOP (#rc+12) DATEADD(DAY, ROW_NUMBER() OVER
(ORDER BY [object_id]) - 7, #fd) FROM sys.all_objects
)
INSERT #thismonth([date], [weekday]) SELECT d, DATEPART(WEEKDAY, d) FROM n;
DELETE #thismonth WHERE [date] < (SELECT MIN([date]) FROM #thismonth WHERE [weekday] = 2)
OR [date] > (SELECT MAX([date]) FROM #thismonth WHERE [weekday] = 1);
;WITH x AS ( SELECT [date], weeknumber, rn = ((ROW_NUMBER() OVER
(ORDER BY [date])-1) / 7) + 1 FROM #thismonth ) UPDATE x SET weeknumber = rn;
-- now, the final query given all that (I've only broken this up to get rid of the vertical scrollbars):
;WITH ranges(w,s,e) AS (
SELECT weeknumber, MIN([date]), MAX([date]) FROM #thismonth GROUP BY weeknumber
)
SELECT [week] = CONVERT(CHAR(10), r.s, 120) + ' - ' + CONVERT(CHAR(10), r.e, 120)
--, SOMETHING , other columns from STATISTICS_?
FROM ranges AS r
-- LEFT OUTER JOIN dbo.STATISTICS_ AS s
-- ON s.TIME_ >= r.s AND s.TIME_ < DATEADD(DAY, 1, r.e)
-- comment this out if you want all the weeks from this month:
WHERE w = (SELECT weeknumber FROM #thismonth WHERE [date] = #today)
GROUP BY r.s, r.e --, SOMETHING
ORDER BY [week];
Results with WHERE clause:
week
-----------------------
2012-05-14 - 2012-05-20
Results without WHERE clause:
week
-----------------------
2012-04-30 - 2012-05-06
2012-05-07 - 2012-05-13
2012-05-14 - 2012-05-20
2012-05-21 - 2012-05-27
2012-05-28 - 2012-06-03
Note that I chose YYYY-MM-DD on purpose. You should avoid regional formatting like M/D/Y especially for input but also for display. No matter how targeted you think your audience is, you're always going to have someone who thinks 05/07/2012 is July 5th, not May 7th. With YYYY-MM-DD there is no ambiguity whatsoever.
Create a calendar table, then you can query week numbers, first/last days of specific weeks and months etc. You can also join on it queries to get a date range etc.
How about a case statement?
case when datepart(day, mydatetime) between 1 and 7 then 1
when datepart(day, mydatetime) between 8 and 14 then 2
...
You'll also have to include the year & month unless you want all the week 1s in the same group.
It's not clear of you want to "group dates by week of month", or alternately "select data from a given week"
If you mean "group" this little snippet should get you 'week of month':
SELECT <stuff>
FROM CP_STATISTICS
WHERE Month(<YOUR DATE COL>) = 5 --april
GROUP BY Year(<YOUR DATE COL>),
Month(<YOUR DATE COL>),
DATEDIFF(week, DATEADD(MONTH, DATEDIFF(MONTH, 0, <YOUR DATE COL>), 0)
, <YOUR DATE COL>) +1
Alternately, if you want "sales for week 1 of April, ordered by date" You could do something like..
DECLARE #targetDate datetime2 = '5/3/2012'
DECLARE #targetWeek int = DATEDIFF(week, DATEADD(MONTH,
DATEDIFF(MONTH, 0, #targetDate), 0), #targetDate) +1
SELECT <stuff>
FROM CP_STATISTICS
WHERE MONTH(#targetDate) = Month(myDateCol) AND
YEAR(#targetDate) = Year (myDateCol) AND
#targetWeek = DATEDIFF(week, DATEADD(MONTH,
DATEDIFF(MONTH, 0, myDateCol), 0), myDateCol) +1
ORDER BY myDateCol
Note, things would get more complicated if you use non-standard weeks, or want to reach a few days into an earlier month for weeks that straddle a month boundary.
EDIT 2
From looking at your 'solved now' section. I think your question is "how do I get data out of a table for a given week?"
Your solution appears to be:
DECLARE #targetDate datetime2 = '5/1/2012'
DECLARE #startDate datetime2 = DATEADD(ww, DATEDIFF(ww,0,targetDate), 0)
DECLARE #endDate datetime2 = DATEADD(ww, DATEDIFF(ww,0,#now), 0)+6
SELECT <stuff>
FROM STATISTICS_
WHERE dateStamp >= #startDate AND dateStamp <= #endDate
Notice how if the date is 5/1 this solution results in a start date of '4/30/2012'. I point this out because your solution crosses month boundaries. This may or may not be desirable.

Getting Number of weeks in a Month from a Datetime Column

I have a table called FcData and the data looks like:
Op_Date
2011-02-14 11:53:40.000
2011-02-17 16:02:19.000
2010-02-14 12:53:40.000
2010-02-17 14:02:19.000
I am looking to get the Number of weeks in That Month from Op_Date. So I am looking for output like:
Op_Date Number of Weeks
2011-02-14 11:53:40.000 5
2011-02-17 16:02:19.000 5
2010-02-14 12:53:40.000 5
2010-02-17 14:02:19.000 5
This page has some good functions to figure out the last day of any given month: http://www.sql-server-helper.com/functions/get-last-day-of-month.aspx
Just wrap the output of that function with a DATEPART(wk, last_day_of_month) call. Combining it with an equivalent call for the 1st-day-of-week will let you get the number of weeks in that month.
Use this to get the number of week for ONE specific date. Replace GetDate() by your date:
declare #dt date = cast(GetDate() as date);
declare #dtstart date = DATEADD(day, -DATEPART(day, #dt) + 1, #dt);
declare #dtend date = dateadd(DAY, -1, DATEADD(MONTH, 1, #dtstart));
WITH dates AS (
SELECT #dtstart ADate
UNION ALL
SELECT DATEADD(day, 1, t.ADate)
FROM dates t
WHERE DATEADD(day, 1, t.ADate) <= #dtend
)
SELECT top 1 DatePart(WEEKDAY, ADate) weekday, COUNT(*) weeks
FROM dates d
group by DatePart(WEEKDAY, ADate)
order by 2 desc
Explained: the CTE creates a result set with all dates for the month of the given date. Then we query the result set, grouping by week day and count the number of occurrences. The max number will give us how many weeks the month overlaps (premise: if the month has 5 Mondays, it will cover five weeks of the year).
Update
Now, if you have multiple dates, you should tweak accordingly, joining your query with the dates CTE.
Here is my take on it, might have missed something.
In Linq:
from u in TblUsers
let date = u.CreateDate.Value
let firstDay = new DateTime(date.Year, date.Month, 1)
let lastDay = firstDay.AddMonths(1)
where u.CreateDate.HasValue
select Math.Ceiling((lastDay - firstDay).TotalDays / 7)
And generated SQL:
-- Region Parameters
DECLARE #p0 Int = 1
DECLARE #p1 Int = 1
DECLARE #p2 Float = 7
-- EndRegion
SELECT CEILING(((CONVERT(Float,CONVERT(BigInt,(((CONVERT(BigInt,DATEDIFF(DAY, [t3].[value], [t3].[value2]))) * 86400000) + DATEDIFF(MILLISECOND, DATEADD(DAY, DATEDIFF(DAY, [t3].[value], [t3].[value2]), [t3].[value]), [t3].[value2])) * 10000))) / 864000000000) / #p2) AS [value]
FROM (
SELECT [t2].[createDate], [t2].[value], DATEADD(MONTH, #p1, [t2].[value]) AS [value2]
FROM (
SELECT [t1].[createDate], CONVERT(DATETIME, CONVERT(NCHAR(2), DATEPART(Month, [t1].[value])) + ('/' + (CONVERT(NCHAR(2), #p0) + ('/' + CONVERT(NCHAR(4), DATEPART(Year, [t1].[value]))))), 101) AS [value]
FROM (
SELECT [t0].[createDate], [t0].[createDate] AS [value]
FROM [tblUser] AS [t0]
) AS [t1]
) AS [t2]
) AS [t3]
WHERE [t3].[createDate] IS NOT NULL
According to this MSDN article: http://msdn.microsoft.com/en-us/library/ms174420.aspx you can only get the current week in the year, not what that month returns.
There may be various approaches to implementing the idea suggested by #Marc B. Here's one, where no UDFs are used but the first and the last days of month are calculated directly:
WITH SampleData AS (
SELECT CAST('20110214' AS datetime) AS Op_Date
UNION ALL SELECT '20110217'
UNION ALL SELECT '20100214'
UNION ALL SELECT '20100217'
UNION ALL SELECT '20090214'
UNION ALL SELECT '20090217'
),
MonthStarts AS (
SELECT
Op_Date,
MonthStart = DATEADD(DAY, 1 - DAY(Op_Date), Op_Date)
/* alternatively: DATEADD(MONTH, DATEDIFF(MONTH, 0, Op_Date), 0) */
FROM FcData
),
Months AS (
SELECT
Op_Date,
MonthStart,
MonthEnd = DATEADD(DAY, -1, DATEADD(MONTH, 1, MonthStart))
FROM FcData
)
Weeks AS (
SELECT
Op_Date,
StartWeek = DATEPART(WEEK, MonthStart),
EndWeek = DATEPART(WEEK, MonthEnd)
FROM MonthStarts
)
SELECT
Op_Date,
NumberOfWeeks = EndWeek - StartWeek + 1
FROM Weeks
All calculations could be done in one SELECT, but I chose to split them into steps and place every step in a separate CTE so it could be seen better how the end result was obtained.
You can get number of weeks per month using the following method.
Datepart(WEEK,
DATEADD(DAY,
-1,
DATEADD(MONTH,
1,
DATEADD(DAY,
1 - DAY(GETDATE()),
GETDATE())))
-
DATEADD(DAY,
1 - DAY(GETDATE()),
GETDATE())
+1
)
Here how you can get accurate amount of weeks:
DECLARE #date DATETIME
SET #date = GETDATE()
SELECT ROUND(cast(datediff(day, dateadd(day, 1-day(#date), #date), dateadd(month, 1, dateadd(day, 1-day(#date), #date))) AS FLOAT) / 7, 2)
With this code for Sep 2014 you'll get 4.29 which is actually true since there're 4 full weeks and 2 more days.

Get the last day of the month in SQL

I need to get the last day of the month given as a date in SQL. If I have the first day of the month, I can do something like this:
DATEADD(DAY, DATEADD(MONTH,'2009-05-01',1), -1)
But does anyone know how to generalize it so I can find the last day of the month for any given date?
From SQL Server 2012 you can use the EOMONTH function.
Returns the last day of the month that contains the specified date,
with an optional offset.
Syntax
EOMONTH ( start_date [, month_to_add ] )
How ... I can find the last day of the month for any given date?
SELECT EOMONTH(#SomeGivenDate)
Here's my version. No string manipulation or casting required, just one call each to the DATEADD, YEAR and MONTH functions:
DECLARE #test DATETIME
SET #test = GETDATE() -- or any other date
SELECT DATEADD(month, ((YEAR(#test) - 1900) * 12) + MONTH(#test), -1)
You could get the days in the date by using the DAY() function:
dateadd(day, -1, dateadd(month, 1, dateadd(day, 1 - day(date), date)))
Works in SQL server
Declare #GivenDate datetime
SET #GivenDate = GETDATE()
Select DATEADD(MM,DATEDIFF(MM, 0, #GivenDate),0) --First day of the month
Select DATEADD(MM,DATEDIFF(MM, -1, #GivenDate),-1) --Last day of the month
I know this is a old question but here is another solution that works for me
SET #dtDate = "your date"
DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#dtDate)+1,0))
And if some one is looking for different examples here is a link http://blog.sqlauthority.com/2007/08/18/sql-server-find-last-day-of-any-month-current-previous-next/
I hope this helps some one else.
stackoverflow Rocks!!!!
For SQL server 2012 or above use EOMONTH to get the last date of month
SQL query to display end date of current month
DECLARE #currentDate DATE = GETDATE()
SELECT EOMONTH (#currentDate) AS CurrentMonthED
SQL query to display end date of Next month
DECLARE #currentDate DATE = GETDATE()
SELECT EOMONTH (#currentDate, 1 ) AS NextMonthED
Based on the statements:
SELECT DATEADD(MONTH, 1, #x) -- Add a month to the supplied date #x
and
SELECT DATEADD(DAY, 0 - DAY(#x), #x) -- Get last day of month previous to the supplied date #x
how about adding a month to date #x and then retrieving the last day of the month previous to that (i.e. The last day of the month of the supplied date)
DECLARE #x DATE = '20-Feb-2012'
SELECT DAY(DATEADD(DAY, 0 - DAY(DATEADD(MONTH, 1, #x)), DATEADD(MONTH, 1, #x)))
Note: This was test using SQL Server 2008 R2
Just extend your formula out a little bit:
dateadd(day, -1,
dateadd(month, 1,
cast(month('5/15/2009') as varchar(2)) +
'/1/' +
cast(year('5/15/2009') as varchar(4)))
This works for me, using Microsoft SQL Server 2005:
DATEADD(d,-1,DATEADD(mm, DATEDIFF(m,0,'2009-05-01')+1,0))
WinSQL to get last day of last month (i.e today is 2017-02-09, returns 2017-01-31:
Select dateadd(day,-day(today()),today())
Try to run the following query, it will give you everything you want :)
Declare #a date =dateadd(mm, Datediff(mm,0,getdate()),0)
Print('First day of Current Month:')
Print(#a)
Print('')
set #a = dateadd(mm, Datediff(mm,0,getdate())+1,-1)
Print('Last day of Current Month:')
Print(#a)
Print('')
Print('First day of Last Month:')
set #a = dateadd(mm, Datediff(mm,0,getdate())-1,0)
Print(#a)
Print('')
Print('Last day of Last Month:')
set #a = dateadd(mm, Datediff(mm,0,getdate()),-1)
Print(#a)
Print('')
Print('First day of Current Week:')
set #a = dateadd(ww, Datediff(ww,0,getdate()),0)
Print(#a)
Print('')
Print('Last day of Current Week:')
set #a = dateadd(ww, Datediff(ww,0,getdate())+1,-1)
Print(#a)
Print('')
Print('First day of Last Week:')
set #a = dateadd(ww, Datediff(ww,0,getdate())-1,0)
Print(#a)
Print('')
Print('Last day of Last Week:')
set #a = dateadd(ww, Datediff(ww,0,getdate()),-1)
Print(#a)
WinSQL: I wanted to return all records for last month:
where DATE01 between dateadd(month,-1,dateadd(day,1,dateadd(day,-day(today()),today()))) and dateadd(day,-day(today()),today())
This does the same thing:
where month(DATE01) = month(dateadd(month,-1,today())) and year(DATE01) = year(dateadd(month,-1,today()))
This query can also be used.
DECLARE #SelectedDate DATE = GETDATE()
SELECT DATEADD(DAY, - DAY(#SelectedDate), DATEADD(MONTH, 1 , #SelectedDate)) EndOfMonth
--## Useful Date Functions
SELECT
GETDATE() AS [DateTime],
CAST(GETDATE() AS DATE) AS [Date],
DAY(GETDATE()) AS [Day of Month],
FORMAT(GETDATE(),'MMMM') AS [Month Name],
FORMAT(GETDATE(),'MMM') AS [Month Short Name],
FORMAT(GETDATE(),'MM') AS [Month No],
YEAR(GETDATE()) AS [Year],
CAST(DATEADD(DD,-(DAY(GETDATE())-1),GETDATE()) AS DATE) AS [Month Start Date],
EOMONTH(GETDATE()) AS [Month End Date],
CAST(DATEADD(M,-1,DATEADD(MM, DATEDIFF(M,0,GETDATE()),0)) AS DATE) AS [Previous Month Start Date],
CAST(DATEADD(S,-1,DATEADD(MM, DATEDIFF(M,0,GETDATE()),0)) AS DATE) AS [Previous Month End Date],
CAST(DATEADD(M,+1,DATEADD(MM, DATEDIFF(M,0,GETDATE()),0)) AS DATE) AS [Next Month Start Date],
CAST(DATEADD(D,-1,DATEADD(MM, DATEDIFF(M,0,GETDATE())+2,0)) AS DATE) AS [Next Month End Date],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE()),0) AS DATE) AS [First Day of Current Week],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE())+1,-1) AS DATE) AS [Last Day of Current Week],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE())-1,0) AS DATE) AS [First Day of Last Week],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE()),-1) AS DATE) AS [Last Day of Last Week],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE())+1,0) AS DATE) AS [First Day of Next Week],
CAST(DATEADD(WW, DATEDIFF(WW,0,GETDATE())+2,-1) AS DATE) AS [Last Day of Next Week]
My 2 cents:
select DATEADD(DAY,-1,DATEADD(MONTH,1,DATEADD(day,(0-(DATEPART(dd,'2008-02-12')-1)),'2008-02-12')))
Raj
using sql server 2005, this works for me:
select dateadd(dd,-1,dateadd(mm,datediff(mm,0,YOUR_DATE)+1,0))
Basically, you get the number of months from the beginning of (SQL Server) time for YOUR_DATE. Then add one to it to get the sequence number of the next month. Then you add this number of months to 0 to get a date that is the first day of the next month. From this you then subtract a day to get to the last day of YOUR_DATE.
Take some base date which is the 31st of some month e.g. '20011231'. Then use the
following procedure (I have given 3 identical examples below, only the #dt value differs).
declare #dt datetime;
set #dt = '20140312'
SELECT DATEADD(month, DATEDIFF(month, '20011231', #dt), '20011231');
set #dt = '20140208'
SELECT DATEADD(month, DATEDIFF(month, '20011231', #dt), '20011231');
set #dt = '20140405'
SELECT DATEADD(month, DATEDIFF(month, '20011231', #dt), '20011231');
Using SQL Server, here is another way to find last day of month :
SELECT DATEADD(MONTH,1,GETDATE())- day(DATEADD(MONTH,1,GETDATE()))
I wrote following function, it works.
It returns datetime data type. Zero hour, minute, second, miliseconds.
CREATE Function [dbo].[fn_GetLastDate]
(
#date datetime
)
returns datetime
as
begin
declare #result datetime
select #result = CHOOSE(month(#date),
DATEADD(DAY, 31 -day(#date), #date),
IIF(YEAR(#date) % 4 = 0, DATEADD(DAY, 29 -day(#date), #date), DATEADD(DAY, 28 -day(#date), #date)),
DATEADD(DAY, 31 -day(#date), #date) ,
DATEADD(DAY, 30 -day(#date), #date),
DATEADD(DAY, 31 -day(#date), #date),
DATEADD(DAY, 30 -day(#date), #date),
DATEADD(DAY, 31 -day(#date), #date),
DATEADD(DAY, 31 -day(#date), #date),
DATEADD(DAY, 30 -day(#date), #date),
DATEADD(DAY, 31 -day(#date), #date),
DATEADD(DAY, 30 -day(#date), #date),
DATEADD(DAY, 31 -day(#date), #date))
return convert(date, #result)
end
It's very easy to use.
2 example:
select [dbo].[fn_GetLastDate]('2016-02-03 12:34:12')
select [dbo].[fn_GetLastDate](GETDATE())
Based on the most voted answer at below link I came up with the following solution:
declare #mydate date= '2020-11-09';
SELECT DATEADD(month, DATEDIFF(month, 0, #mydate)+1, -1) AS lastOfMonth
link: How can I select the first day of a month in SQL?
I couldn't find an answer that worked in regular SQL, so I brute forced an answer:
SELECT *
FROM orders o
WHERE (MONTH(o.OrderDate) IN ('01','03','05','07','08','10','12') AND DAY(o.OrderDate) = '31')
OR (MONTH(o.OrderDate) IN ('04','06','09','11') AND DAY(o.OrderDate) = '30')
OR (MONTH(o.OrderDate) IN ('02') AND DAY(o.OrderDate) = '28')
---Start/End of previous Month
Declare #StartDate datetime, #EndDate datetime
set #StartDate = DATEADD(month, DATEDIFF(month, 0, GETDATE())-1,0)
set #EndDate = EOMONTH (DATEADD(month, DATEDIFF(month, 0, GETDATE())-1,0))
SELECT #StartDate,#EndDate