How to select the past three months data from a date parameter - sql

I would like to display the name of the month along with a count for each of these months. But I only want the past 3 months from a date parameter that the user will select.
This is what I have currently:
SELECT
DATENAME(month, DateDue),
COUNT(SiteAudit.SiteAuditID) AS SiteAuditID
FROM
SiteAudit
WHERE
DateDue >= Dateadd(month, -3, #Date)
GROUP BY
DATENAME(month, DateDue)
I'm not sure where I am going wrong because now I am getting more than 3 months returned.
If anyone could please help I would greatly appreciate it.
Thank you

You should use DateDue between DateAdd(month, -3, #Date) and #Date
Your original query will select data which due date after the #Date
Complete query:
SELECT
DATENAME(month, DateDue),
COUNT(SiteAudit.SiteAuditID) AS SiteAuditID
FROM
SiteAudit
WHERE
DateDue BETWEEN Dateadd(month, -3, #Date) AND #Date
GROUP BY
DATENAME(month, DateDue)

Related

Getting the week number as alias in sql analysis

this is my first question here. Hopefully I´m clear enough what I´m searching for.
My problem is following:
On this analysis I want to get from the last 7 weeks, the summarized prices of each week. Its working with out any problems, but now I would like to add the weeks number of each week as alias.
In my tests I was using for example something like this:
DECLARE #week7 varchar(10)
SET #week7 = DATEPART(wk, GetDate())
One of my problems is, that I´m not allowed to work with "EXEC".
This is just an example of my analysis:
SELECT DISTINCT(
SELECT SUM(Price)
FROM tblBookingdata
WHERE(Datum BETWEEN DATEADD(wk, -7, DATEADD(DAY, 1 - DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))) AND DATEADD(wk, -6, DATEADD(DAY, 1 - DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))))) AS '7 weeks ago', (
SELECT SUM(Price)
FROM tblBookingdata
WHERE(Datum BETWEEN DATEADD(wk, -6, DATEADD(DAY, 1 - DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))) AND DATEADD(wk, -5, DATEADD(DAY, 1 - DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))))) AS '6 weeks ago'
I would like the column name to show the week number from each sub select. That the output would be for example for this week: 40 (as column name) and 900 as price summary.
So I tried to work here with DECLARE and assign #week7 for example with the current week number. But here I got stuck, due it seems like I need to work here with EXEC.
Is this only possible with "EXEC" or are there any other solutions to solve this? I was looking in the www, but currently I´m stucking a bit. Thankful for every help! :)
I think the DateDiff function is your friend here. Are you using SQL Server? This won't display a row for the week if there are zero records in that week, but this should be close to what you want.
select WeeksAgo, sum(Price) as Price from (
select
Price
,Datediff(wk, Datum, getDate()) as WeeksAgo
,Datum --not used
from
tblBookingdata
)DataByWeek
where WeeksAgo between 0 and 7 --should this be 0-6?
group by WeeksAgo
I think you're looking for something like this. The prior 7 weeks are calculated from GETDATE based on a numbers table with 1, 2, 3, ... 7. Then the booking Prices are summarized by week where the Datum is within the prior 7 weeks. This will display NULL in price_sum if there were no sales that week.
drop table if exists #tblBookingdata;
go
create table #tblBookingdata(
Datum date not null,
Price int not null);
go
;with
weeks_cte(wk) as (
select datepart(wk, dateadd(wk, w*-1, getdate()))
from (values (1),(2),(3),(4),(5),(6),(7)) v(w)),
bookings_cte(wk, price_sum) as (
select datepart(wk, Datum), sum(Price)
from #tblBookingdata
where Datum>dateadd(wk, -7, getdate())
group by datepart(wk, Datum))
select *
from weeks_cte wc
left join bookings_cte b on wc.wk=b.wk;

Retrieving last months data when last month is also last year?

I have the following Where clause in several queries. This successfully retrieves the past months data. Now the year has changed, the query can't find any data (December 2018 hasn't happened yet!). How can I change the Where clause to overcome this?
select *
from somedatabase a
WHERE DATEPART(m, a.meetDate) = DATEPART(m, DATEADD(m, -1, getdate()))
and DATEPART(yyyy, a.meetDate) = DATEPART(yyyy, getdate())
Many thanks and any assistance very gratefully received.
My normal way of rounding down to the start of the current month is:
DATEADD(month, DATEDIFF(month, 0, getDate()), 0)
Find out how many whole months there have been since date 0
Then add that many months to date 0
Always gives the start of the month (as date 0 is the start of a month)
Is not affected by leap year, year boundaries, months of various length, etc
This then allows me to do things like...
WHERE
a.meetDate >= DATEADD(month, DATEDIFF(month, 0, getDate()) - 1, 0) -- start of last month
AND a.meetDate < DATEADD(month, DATEDIFF(month, 0, getDate()) , 0) -- start of this month
By having the calculations on the right hand side you make maximum use of indexes.
Here is one way:
WHERE DATEPART(month, a.meetDate) = DATEPART(month, DATEADD(m, -1, getdate())) AND
DATEPART(year, a.meetDate) = DATEPART(year, DATEADD(m, -1, getdate()))
That is, subtract one month for both comparisons.
Actually, a simpler way is to use the strange rules of DATE_DIFF():
WHERE DATEDIFF(month, a.meetDate, getdate()) = 1
Neither of these can make use of an index. For that, the expression is a little more complicated:
WHERE a.meetDate >= DATEFROMPARTS(YEAR(DATEADD(MONTH, -1, GETDATE()),
MONTH(DATEADD(MONTH, -1, GETDATE()),
1) AND
a.meetDate < DATEADD(DAY, 1 - DAY(GETDATE()), CAST(GETDATE() as DATE))

Group by Weeks for successive years

I am trying to aggregate data by weeks. My sample query looks like
SET DATEFIRST 1
Select ID,
DATENAME(week, p.SellingDate) as SellingWeek,
DATENAME(year, p.SellingDate) as SellingYear,
SUM(Quantity),
SUM(Revenue)
From dbo.Sales
Where
p.SellingDate >=’2015-12-20’ and P.SellingDate < ’2016-02-27’
Group by ID,
DATENAME(week, p.SellingDate),
DATENAME(year, p.SellingDate)
When I try to do this, I am facing an issue:
The query returns correct data but the issue appears in the last week of 2015. It considers only the days (12/28 to 12/31) that are part of 2015 as the 53rd week and it considers the remaining part (01/01 to 01/03) as a new week of 2016. I only one row that has data for the whole week i.e. 12/28 to 01/03) but SQL Server returns 2 rows. Is there a workaround this?
I would think you want to create a construct for grouping on week start and week end, then using that to group by for your aggregation clauses.
SET DATEFIRST 1
Select DATEADD(dd, -(DATEPART(dw, p.SellingDate)-1), p.SellingDate) AS [WeekStart],
DATEADD(dd, 7-(DATEPART(dw, p.SellingDate)), p.SellingDate) AS [WeekEnd],
SUM(Quantity),
SUM(Revenue)
From dbo.Sales
Where
p.SellingDate >= '2015-12-20' and P.SellingDate < '2016-02-27'
Group by ID,
DATEADD(dd, -(DATEPART(dw, p.SellingDate)-1), p.SellingDate),
DATEADD(dd, 7-(DATEPART(dw, p.SellingDate)), p.SellingDate)
You can fix this by setting the week not based on the date of the sale but rather on the monday of week of the date of the sale.
select
getdate() as today
datename(week, dateadd(dd,-1* (datepart(weekday, getdate())-1),getdate())) as monday,

Get Sum of all Distinct in a week

I am wondering where exactly i am not clear with this query. I want to get the count of all distinct RepIDs that worked in a particular week. This is In SQL Server 2005. Thank you!!
This query gives me distinct RepID's for the whole week. I want to count RepID twice if he has records on 2 different days but count only once even if he has more than 1 record for any partiular day.. I hope i am clear. I am sorry that i was not clear before! Thank you!
Select count(distinct(RepID)) as SalesPeople from DailyInfo
where Date > DATEADD(dd, -(DATEPART(dw, #Date)-1), #Date)
and Date < DATEADD(dd, 7-(DATEPART(dw, #Date)), #Date)
You can make unique combinations of the RepID+Date to make it unique (SQLFiddle):
SELECT COUNT(distinct RIGHT(DateDiff(d,0,Date),10)
+RIGHT(RepID,10)) as SalesPeople
FROM DailyInfo
WHERE Date > DATEADD(dd, -(DATEPART(dw, #Date)-1), #Date)
AND Date < DATEADD(dd, 7-(DATEPART(dw, #Date)), #Date);
I have assumed DailyInfo.Date can contain time information. You can swap DateDiff(d,0,Date) above for just Date. Similarly, CAST(DateDiff(d,0,Date) as datetime) below can be just `Date.
Below is the query if you needed to see the breakdown for each day.
SELECT CAST(DateDiff(d,0,Date) as datetime) TheDay,
COUNT(distinct RepID) as SalesPeople
FROM DailyInfo
WHERE Date > DATEADD(dd, -(DATEPART(dw, #Date)-1), #Date)
AND Date < DATEADD(dd, 7-(DATEPART(dw, #Date)), #Date)
GROUP BY CAST(DateDiff(d,0,Date) as datetime) -- by day
ORDER BY TheDay
Let me answer this by suggesting how you should think about the problem. You are looking for the number of reps per day. So, your query should have a summary (subquery) at this level. Then, you can count the number of days per week.
Assuming that your date does not have any time component, you can use the following:
select count(*)
from (select RepId, date as thedate, count(*) as NumOnDay
from DailyInfo
group by RepId, date
where Date > DATEADD(dd, -(DATEPART(dw, #Date)-1), #Date)
and Date < DATEADD(dd, 7-(DATEPART(dw, #Date)), #Date)
) rd
Alternatively, you could count the number of days that a rep worked during a week and then add these up:
select sum(numdates)
from (select RepId, count(distinct date) as numdates
from DailyInfo
group by RepId
where Date > DATEADD(dd, -(DATEPART(dw, #Date)-1), #Date)
and Date < DATEADD(dd, 7-(DATEPART(dw, #Date)), #Date)
) rd
If your date field has a time component, then you need to remove the time component for this to work. Or use some trick such as day(date), since the day function will returns a different value for each date in a week. In later versions of SQL Server, you can just cast(date as date), if the original date is datetime.
Select count(1)
from DailyInfo
group by convert(varchar(10),[date], 120)
where [put your condition here]
You could use a CTE, but might be over kill. And have the group by the day in the CTE and you need to do is a sum of the totals.
WITH cte ([day], total) as
(
Select DATENAME(DW,[Date]), count(distinct(RepID)) as SalesPeople from DailyInfo
where [Date] > DATEADD(dd, -(DATEPART(dw, #Date)-1), #Date) and [Date] < DATEADD(dd, 7-(DATEPART(dw, #Date)), #Date)
GROUP BY DATENAME(DW,[Date])
)
select SUM(total) FROM cte;
To do what I think you want you need to group by day, and filter on the week, and then do a distinct on the result:
Select Distinct(RepID)
From (Select RepID
Group By DateDiff(day, 0, Date)
From DailyInfo
Where Date > DateAdd(dd, -(DATEPART(dw, #Date)-1), #Date)
And Date < DateAdd(dd, 7-(DATEPART(dw, #Date)), #Date)

Getting the previous months data

This seems to have been answered several times for the past 30 days. But seemingly not what I need.
If, for example, today is July 10th, 2012. I'm looking to pull all of June's data. I will need to run this query several days after the start of each month
There is certainly better ways to do this, but one way would be this:
DECLARE #Date DATETIME
SET #Date = '20120710'
SELECT *
FROM YourTable
WHERE YourDateColumn >= CONVERT(VARCHAR(6),DATEADD(MONTH,-1,#Date),112)+'01'
AND YourDateColumn < CONVERT(VARCHAR(6),#Date,112)+'01')
-- first day of previous month
select DateAdd(Month, DateDiff(Month, 0, GetDate())-1,0)
-- last day of previous month
Select DateAdd(day,-1,DateAdd(Month,1,DateAdd(Month,
DateDiff(Month, 0,GETDATE())-1,0)))
Please replace GETDATE() with your date column
Ah, in that case you need something like:
SELECT *
FROM
reporting_table_name_goes_here
WHERE
DATEPART(month, YourDateColumn) = DATEPART(month, DATEADD(month, -1, getdate()))
AND DATEPART(year, YourDateColumn) = DATEPART(year, DATEADD(month, -1, getdate()))
Check out MSDN for details.