SQL Date Logic Clause - sql

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)));

Related

How can i change this Dateadd to selective dates

In the end of my big procedure i have previously made it so i can write example: "2" to get sales information for February. But now i want to change this so i can write the specific dates, because we want to fetch some more data.
Example of what I want to write: 29.01.2014 - 28.02.2014
Code:
WHERE isa.sales_date >= Dateadd(mm, ( #year - 1900 ) * 12 + ( #month - 1 ),
0)
AND isa.sales_date < Dateadd(mm, ( #year - 1900 ) * 12 + #month, 0)
Try:
Have two parameters:
#startDate varchar(10) --2014-01-01
#endDate varchar(10) --2014-01-29
And modify code like:
WHERE isa.sales_date >= convert(datetime, #startDate, 120)
AND isa.sales_date < DATEADD(DAY, 1, (convert(datetime, #endDate, 120))
The DATEADD part is to include all sales until the end of the last day.

Get last Friday's Date unless today is Friday using T-SQL

I'm trying to get the correct SQL code to obtain last Friday's date. A few days ago, I thought I had my code correct. But just noticed that it's getting last week's Friday date, not the last Friday. The day I'm writing this question is Saturday, 8/11/2012 # 12:23am. In SQL Server, this code is returning Friday, 8/3/2012. However, I want this to return Friday, 8/10/2012 instead. How can I fix this code? Since we're getting to specifics here, if the current day is Friday, then I want to return today's date. So if it were yesterday (8/10/2012) and I ran this code yesterday, then I would want this code to return 8/10/2012, not 8/3/2012.
SELECT DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, GETDATE()), 0))
try this:
declare #date datetime;
set #date='2012-08-09'
SELECT case when datepart(weekday, #date) >5 then
DATEADD(DAY, +4, DATEADD(WEEK, DATEDIFF(WEEK, 0, #date), 0))
else DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, #date), 0)) end
result:
2012-08-03
Example2:
declare #date datetime;
set #date='2012-08-10'
SELECT case when datepart(weekday, #date) >5 then
DATEADD(DAY, +4, DATEADD(WEEK, DATEDIFF(WEEK, 0, #date), 0))
else DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, #date), 0)) end
result:
2012-08-10
Modular arithmetic is the most direct approach, and order of operations decides how Fridays are treated:
DECLARE #test_date DATETIME = '2012-09-28'
SELECT DATEADD(d,-1-(DATEPART(dw,#test_date) % 7),#test_date) AS Last_Friday
,DATEADD(d,-(DATEPART(dw,#test_date+1) % 7),#test_date) AS This_Friday
Use this :
SELECT DATEADD(day, (DATEDIFF (day, '19800104', CURRENT_TIMESTAMP) / 7) * 7, '19800104') as Last_Friday
None of that? Try this:
DECLARE #D DATE = GETDATE()
SELECT DATEADD(D,-(DATEPART(W,#D)+1)%7,#D)
A tested function which works no matter what ##DATEFIRST is set to.
-- ==============
-- fn_Get_Week_Ending_forDate
-- Author: Shawn C. Teague
-- Create date: 2017
-- Modified date:
-- Description: Returns the Week Ending Date on DayOfWeek for a given stop date
-- Parameters: DayOfWeek varchar(10) i.e. Monday,Tues,Wed,Friday,Sat,Su,1-7
-- DateInWeek DATE
-- ==============
CREATE FUNCTION [dbo].[fn_Get_Week_Ending_forDate] (
#DayOfWeek VARCHAR(10),#DateInWeek DATE)
RETURNS DATE
AS
BEGIN
DECLARE #End_Date DATE
,#DoW TINYINT
SET #DoW = CASE WHEN ISNUMERIC(#DayOfWeek) = 1
THEN CAST(#DayOfWeek AS TINYINT)
WHEN #DayOfWeek like 'Su%' THEN 1
WHEN #DayOfWeek like 'M%' THEN 2
WHEN #DayOfWeek like 'Tu%' THEN 3
WHEN #DayOfWeek like 'W%' THEN 4
WHEN #DayOfWeek like 'Th%' THEN 5
WHEN #DayOfWeek like 'F%' THEN 6
ELSE 7
END
select #End_Date =
CAST(DATEADD(DAY,
CASE WHEN (#DoW - (((##datefirst) + datepart(weekday, #DateInWeek)) % 7)) = 7
THEN 0
WHEN (#DoW - (((##datefirst) + datepart(weekday, #DateInWeek)) % 7)) < 0
THEN 7 - ABS(#DoW - (((##datefirst) + datepart(weekday, #DateInWeek)) % 7))
ELSE (#DoW - (((##datefirst) + datepart(weekday, #DateInWeek)) % 7) )
END
,#DateInWeek) AS DATE)
RETURN #End_Date
END
This will give you the Friday of Last week.
SELECT DATEADD(day, -3 - (DATEPART(dw, GETDATE()) + ##DATEFIRST - 2) % 7, GETDATE()) AS LastWeekFriday
This will give you last Friday's Date.
SELECT DATEADD(day, +4 - (DATEPART(dw, GETDATE()) + ##DATEFIRST-2) % 7, GETDATE()) AS LastFriday
select convert(varchar(10),dateadd(d, -((datepart(weekday, getdate()) + 1 + ##DATEFIRST) % 7), getdate()),101)
Following code can be use to return any last day by replacing #dw_wk, test case below use friday as asked in original questions
DECLARE #date SMALLDATETIME
,#dw_wk INT --last day of week required - its integer representation
,#dw_day int --current day integer reprsentation
SELECT #date='8/11/2012'
SELECT #dw_day=DATEPART(dw,#date)
SELECT #dw_wk=DATEPART(dw,'1/2/2015') --Just trying not to hard code 5 for friday, here we can substitute with any date which is friday
SELECT case when #dw_day<#dw_wk then DATEADD(DAY, #dw_wk-7-#dw_day,#date) else DATEADD(DAY,#dw_wk-#dw_day, #date) END
Here's an answer I found here adapted from MySQL to T-SQL that is a one liner using all basic arithmetic (no division or modulos):
SELECT DATEADD(d, 1 - datepart(weekday, dateadd(d, 2, GETDATE())), GETDATE())
You can do all sorts of combinations of this, like get next Friday's date unless today is Friday, or get last Thursday's date unless today is Thursday by just changing the 1 and the 2 literals in the command:
Get next Friday's date unless today is Friday
SELECT DATEADD(d, 7 - datepart(weekday, dateadd(d, 1, GETDATE())), GETDATE())
Get last Thursday's date unless today is Thursday
SELECT DATEADD(d, 1 - datepart(weekday, dateadd(d, 3, GETDATE())), GETDATE())
I have had this same issue, and created the following example to show how to do this and to make it flexible to use whichever day of the week you want. I have different lines in the SELECT statement, just to show what this is doing, but you just need the [Results] line to get the answer. I also used variables for the current date and the target day of the week, to make it easier to see what needs to change.
Finally, there is an example of results when you want to include the current date as a possible example or when you always want to go back to the previous week.
DECLARE #GetDate AS DATETIME = GETDATE();
DECLARE #Target INT = 6 -- 6 = Friday
SELECT
#GetDate AS [Current Date] ,
DATEPART(dw, #GetDate) AS [Current Day of Week],
#Target AS [Target Day of Week] ,
IIF(#Target = DATEPART(dw, #GetDate), 'Yes' , 'No') AS [IsMatch] ,
IIF(#Target = DATEPART(dw, #GetDate), 0 , ((7 + #Target - DATEPART(dw, #GetDate)) % 7) - 7) AS [DateAdjust] ,
------------------------------------------------------------------------------------------------------------------------------------------------
CAST(IIF(#Target = DATEPART(dw, #GetDate), #GetDate, DATEADD(d, (((7 + #Target - DATEPART(dw, #GetDate)) % 7) - 7), #GetDate)) AS DATE) AS [Result]
------------------------------------------------------------------------------------------------------------------------------------------------
;
SELECT
#GetDate AS [Current Date] ,
DATEPART(dw, #GetDate) AS [Current Day of Week],
#Target AS [Target Day of Week] ,
((7 + #Target - DATEPART(dw, #GetDate)) % 7) - 7 AS [DateAdjust] ,
------------------------------------------------------------------------------------------------------------------------------------------------
CAST(DATEADD(d, (((7 + #Target - DATEPART(dw, #GetDate)) % 7) - 7), #GetDate) AS DATE) AS [NOTIncludeCurrent]
------------------------------------------------------------------------------------------------------------------------------------------------
;
SELECT DECODE(TO_CHAR(SYSDATE,'DY'),'FRI',SYSDATE,NEXT_DAY(SYSDATE, 'FRI')-7) FROM dual;

SQL Date Function

I may be using the wrong term (hence why I can't find it on google).
"Are there any functions or common code for Accounting Months Deliminations?"
For Example, this month started on a friday but on most accounting journals the weeks are measured by the first monday of the month so instead of having the 1st of July it would be the 4th of July. Same thing with the month end (29th instead of the 31st)
Again, I'm sure someone has created this 'wheel' before, and I can't seem to find it for the life of me.
The following query assumes a table, SalesTable, has a field called Amount (the value you want to sum) and a field called SaleDate (the date on which the sale occured.) It also assumes that accounting months begin the first Monday of the month and end on the Sunday prior to the beginning of the next accounting month.
Again, I highly recommend a table-based approach to this, but if you can't modify the schema, this should do the trick in T-SQL:
SELECT
CASE WHEN s.SaleDate < DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEADD(DAY, 6 - DATEPART(DAY, s.SaleDate ),s.SaleDate )), 0)
THEN DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEADD(DAY, 6 - DATEPART(DAY, DATEADD(day,-7,s.SaleDate) ),DATEADD(day,-7,s.SaleDate) )), 0)
ELSE DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEADD(DAY, 6 - DATEPART(DAY, s.SaleDate ),s.SaleDate )), 0)
END AccountingMonth,
SUM(s.Amount) TotalSales
FROM SalesTable s
GROUP BY
CASE WHEN s.SaleDate < DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEADD(DAY, 6 - DATEPART(DAY, s.SaleDate ),s.SaleDate )), 0)
THEN DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEADD(DAY, 6 - DATEPART(DAY, DATEADD(day,-7,s.SaleDate) ),DATEADD(day,-7,s.SaleDate) )), 0)
ELSE DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEADD(DAY, 6 - DATEPART(DAY, s.SaleDate ),s.SaleDate )), 0)
END
Note that the AccountingMonth return field actually contains the date of the first Monday of the month. In actual practice, you probably want to wrap this entire query in another query that reformats AccountingMonth to whatever you like... "2011-07", "2011-08", etc.
Here's how it works: This bit of code is the important part:
DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEADD(DAY, 6 - DATEPART(DAY, s.SaleDate ),s.SaleDate )), 0)
It takes any date and returns the first Monday of the month in which that date occurred. In your case, however, you have to do a little more work because a sale might have occurred in the window between the first of the month and the first Monday of the month. The CASE statement detects that scenario and, if it's true, subtracts a week off of the date before calculating the first Monday.
Good luck!
-Michael
I have some code that takes in a year and month and returns the fiscal start and end dates. Perhaps this will give you something to go by:
DECLARE #yr int;
DECLARE #mo int;
SELECT #yr = 2011
SELECT #mo = 7
DECLARE #FiscalMonthStartDate datetime
DECLARE #FiscalMonthEndDate datetime
DECLARE #startOfMonth datetime
DECLARE #startOfNextMonth datetime
select #startOfMonth = CAST((CAST(#yr AS VARCHAR(4)) + '-' + CAST(#mo AS VARCHAR(2)) + '-' + '01') as DATE)
select #startOfNextMonth = CAST((CAST(#yr AS VARCHAR(4)) + '-' + CAST((#mo + 1) AS VARCHAR(2)) + '-' + '01') as DATE)
SELECT #FiscalMonthStartDate =
CASE
WHEN DATEPART(DW,#startOfMonth) = 0
THEN DATEADD(DD, 1, #startOfMonth)
ELSE
DATEADD(DD, 8 - DATEPART(DW,#startOfMonth), #startOfMonth)
END
SELECT #FiscalMonthEndDate =
CASE
WHEN DATEPART(DW,#startOfNextMonth) = 0
THEN DATEADD(DD, 1, #startOfNextMonth)
ELSE
DATEADD(DD, 8 - DATEPART(DW,#startOfNextMonth), #startOfNextMonth)
END
-- subtract one day to get end of fiscal month (not start of next fiscal month)
SELECT #FiscalMonthEndDate = DATEADD(DD, -1, #FiscalMonthEndDate)
SELECT #FiscalMonthStartDate, #FiscalMonthEndDate

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

Compare current date with stored datetime using month an year only

Using SQL Server 2005 I have a field that contains a datetime value.
What I am trying to do is create 2 queries:
Compare to see if stored datetime is of the same month+year as current date
Compare to see if stored datetime is of the same year as current date
There is probably a simple solution but I keep hitting brick walls using various samples I can find, any thoughts?
Thanks in advance.
Compare the parts of the date:
WHERE YEAR( columnName ) = YEAR( getDate() )
While the other answers will work, they all suffer from the same problem: they apply a transformation to the column and therefore will never utilize an index on that column.
To search the date without a transformation, you need a couple built-in functions and some math. Example below:
--create a table to hold our example values
create table #DateSearch
(
TheDate datetime not null
)
insert into #DateSearch (TheDate)
--today
select getdate()
union all
--a month in advance
select dateadd(month, 1, getdate())
union all
--a year in advance
select dateadd(year, 1, getdate())
go
--declare variables to make things a little easier to see
declare #StartDate datetime, #EndDate datetime
--search for "same month+year as current date"
select #StartDate = dateadd(month, datediff(month, 0, getdate()), 0), #EndDate = dateadd(month, datediff(month, 0, getdate()) + 1, 0)
select #StartDate [StartDate], #EndDate [EndDate], TheDate from #DateSearch
where TheDate >= #StartDate and TheDate < #EndDate
--search for "same year as current date"
select #StartDate = dateadd(year, datediff(year, 0, getdate()), 0), #EndDate = dateadd(year, datediff(year, 0, getdate()) + 1, 0)
select #StartDate [StartDate], #EndDate [EndDate], TheDate from #DateSearch
where TheDate >= #StartDate and TheDate < #EndDate
What the statement does to avoid the transformations, is find all values greater-than or equal-to the beginning of the current time period (month or year) AND all values less-than the beginning of the next (invalid) time period. This solves our index problem and also mitigates any issues related to 3ms rounding in the DATETIME type.
SELECT * FROM atable
WHERE
YEAR( adate ) = YEAR( GETDATE() )
AND
MONTH( adate ) = MONTH( GETDATE() )
It sounds to me like DATEDIFF is exactly what you need:
-- #1 same month and year
SELECT *
FROM your_table
WHERE DATEDIFF(month, your_column, GETDATE()) = 0
-- #2 same year
SELECT *
FROM your_table
WHERE DATEDIFF(year, your_column, GETDATE()) = 0
The datepart function lets you pull the bits you need:
declare #d1 as datetime
declare #d2 as datetime
if datepart(yy, #d1) = datepart(yy, #d2) and datepart(mm, #d1) = datepart(mm, #d2) begin
print 'same'
end
You can use something like this
a)
select *
from table
where MONTH(field) = MONTH(GetDATE())
and YEAR(field) = YEAR(GetDATE())
b)
select *
from table
where YEAR(field) = YEAR(GetDATE())