I have a query that returns all records for the week which starts on Monday. I'm trying to get the record count for each day of the week with no success.
The Original Query:
SET DATEFIRST 1 -- Beginning of week is Monday
SELECT DateTime, ScanPoints, PostPoints
FROM SmartTappScanLog
WHERE DateTime >= dateadd(day, 1-datepart(dw, getdate()), CONVERT(date,getdate()))
AND DateTime < dateadd(day, 8-datepart(dw, getdate()), CONVERT(date,getdate()))
AND UserID = '1' AND BeerID = '3'
ORDER BY DateTime ASC
I've tried several things including Count(DateTime) with a Group By:
SET DATEFIRST 1 -- Beginning of week is Monday
SELECT Count(DateTime), ScanPoints, PostPoints
FROM SmartTappScanLog
WHERE DateTime >= dateadd(day, 1-datepart(dw, getdate()), CONVERT(date,getdate()))
AND DateTime < dateadd(day, 8-datepart(dw, getdate()), CONVERT(date,getdate()))
AND UserID = '1' AND BeerID = '3'
ORDER BY DateTime ASC
GROUP BY DateTime
The error indicates there is a syntax error near GROUP.
Your query has a few issues,
GROUP BY must come before ORDER BY.
Non-aggregated columns selected must also be in the GROUP BY clause
SELECT Count(DateTime), ScanPoints, PostPoints...
GROUP BY ScanPoints, PostPoints
I assume your column DateTime actually contains a date and time. Grouping By this will give you a record for each unique date/time value in your data. Since you're wanting daily data, you should strip off the time by converting it to a date. By the way, DateTime is a data type and a terrible name for a column.
I prefer not to use DATEFIRST as it does not affect all of the date functions equally. If you later use a datediff with weeks, the results may be wrong.
My company also uses Monday as the start of the week. By calculating the shifted first day of the week, you can change which week a Sunday belongs to.
CAST(DATEADD( DAY,
(DATEPART( WEEKDAY, [YourDate] ) + 5) % 7 * -1,
[YourDate] )
AS DATE) AS FirstDayOfWeekIsMonday
Using the FirstDayOfWeekIsMonday column for your week filtering/grouping will ensure that the Sunday is associated with the prior Monday.
As an added bonus, this expression is SARGable so indexes on YourDate can still be used.
Give this a try ( Not tested)
SET DATEFIRST 1 -- Beginning of week is Monday
SELECT datepart(dw, DateTime) as Day, ScanPoints, PostPoints, Count(DateTime) as Recs,
FROM SmartTappScanLog
WHERE DateTime >= dateadd(day, 1-datepart(dw, getdate()), CONVERT(date,getdate()))
AND DateTime < dateadd(day, 8-datepart(dw, getdate()), CONVERT(date,getdate()))
AND UserID = '1' AND BeerID = '3'
GROUP BY datepart(dw, DateTime) , ScanPoints, PostPoints
ORDER BY datepart(dw, DateTime) , ScanPoints, PostPoints
Group by should appear before Order by.
Your Query should be build as below:
SET DATEFIRST 1 -- Beginning of week is Monday
SELECT Count(DateTime), ScanPoints, PostPoints
FROM SmartTappScanLog
WHERE DateTime >=
dateadd(day, 1-datepart(dw, getdate()), CONVERT(date,getdate()))
AND DateTime <
dateadd(day, 8-datepart(dw, getdate()), CONVERT(date,getdate()))
AND UserID = '1' AND BeerID = '3'
GROUP BY DateTime
ORDER BY DateTime ASC
I want to pull back all the rows that have a report date from the previous 3 months. So If I'm running the code in March 2015, I want to pull back data from Dec14, Jan15, Feb 15.
I've tried to use the following but not had much success
Select * from table
where DATEPART(month, ReportDate) between Month(DATEADD(month, -1,GETDATE())) and Month(DATEADD(month, -3,GETDATE()))
You can get the first day of the current month using:
SELECT DATEADD(MONTH, DATEDIFF(MONTH, '1900001', GETDATE()), '19000101')
This basically just gets the number of months between now, and a fixed date, then adds this number of months back to the same fixed date, to get the first of the current month. Then it is just a case of adding this into your query, so your pseudo code is:
WHERE ReportDate < [start of this month]
AND ReportDate >= [start of 4 months ago]
And your actual code is:
WHERE ReportDate < DATEADD(MONTH, DATEDIFF(MONTH, '19000101', GETDATE()), '19000101')
AND ReportDate >= DATEADD(MONTH, DATEDIFF(MONTH, '19000401', GETDATE()), '19000101');
Note that I have removed the function from the ReportDate column which will make your predicate sargable
Here are a couple of good articles on querying date ranges:
Bad habits to kick : mis-handling date / range queries
What do BETWEEN and the devil have in common?
You can try something like this,
create table Test(id int, TranDate datetime)
insert into Test (id, TranDate) values
(1, '2014-12-12'),
(2, '2014-11-10'),
(3, '2015-04-01'),
(4, '2015-02-02'),
(5, '2015-01-01')
declare #FromDate DateTime = dateadd(month, -4, getdate())
declare #ToDate DateTime = dateadd(month, -1, getdate())
select * from Test where TranDate >= #FromDate and TranDate <= #ToDate
Sql Fiddle Demo
Dont use BETWEEN clause in sql.
Try this:
SELECT *
FROM YourTableName
WHERE ReportDate
BETWEEN DATEADD(month, -4,GETDATE()) AND
DATEADD(month, -1,GETDATE())
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
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