I have data in the below format:
TrDate:2018-01-01 00:00:00.000 | Amount: 10.00
TrDate:2018-01-02 00:00:00.000 | Amount: 20.00
And I want to consolidate data at weekly level:
Week:1 | Start Date: | End Date:| Total Amount
I have query which consolidates data at weekly but I do not know how to get the start and end dates for the respective week. This was my query:
SELECT DATEPART(wk, trdate) weekno,
round(SUM(amount),2) AS total_amount
FROM <table>
GROUP BY DATEPART(wk, trdate);
FYI: Week starts from Sunday and Ends on Saturday.
Try this:
select weekno, weekStart, weekEnd, round(SUM(amount),2) AS total_amount from
(
SELECT
DATEPART(wk, trdate) weekno,
DATEADD(dd, -(DATEPART(dw, trdate)-1), trdate) [WeekStart],
DATEADD(dd, 7-(DATEPART(dw, trdate)), trdate) [WeekEnd],
amount
from table1
)t
group by Weekno, weekstart, weekend
You can use this expression to find the previous Sunday for a given date (it works regardless of @@DATEFIRST
setting):
SELECT DATEADD(DAY, -CASE DATENAME(WEEKDAY, <date>)
WHEN 'SUNDAY' THEN 0
WHEN 'MONDAY' THEN 1
WHEN 'TUESDAY' THEN 2
WHEN 'WEDNESDAY' THEN 3
WHEN 'THURSDAY' THEN 4
WHEN 'FRIDAY' THEN 5
WHEN 'SATURDAY' THEN 6
END, <date>) AS weekstart
You can use it in your query as follows:
SELECT weekno, total_amount, DATEADD(DAY, -CASE DATENAME(WEEKDAY, refdate)
WHEN 'SUNDAY' THEN 0
WHEN 'MONDAY' THEN 1
WHEN 'TUESDAY' THEN 2
WHEN 'WEDNESDAY' THEN 3
WHEN 'THURSDAY' THEN 4
WHEN 'FRIDAY' THEN 5
WHEN 'SATURDAY' THEN 6
END, refdate) AS weekstart, DATEADD(DAY, CASE DATENAME(WEEKDAY, refdate)
WHEN 'SUNDAY' THEN 6
WHEN 'MONDAY' THEN 5
WHEN 'TUESDAY' THEN 4
WHEN 'WEDNESDAY' THEN 3
WHEN 'THURSDAY' THEN 2
WHEN 'FRIDAY' THEN 1
WHEN 'SATURDAY' THEN 0
END, refdate) AS weekend
FROM (
SELECT DATEPART(wk, trdate) weekno
, ROUND(SUM(amount),2) AS total_amount
, MIN(trdate) AS refdate
FROM t
GROUP BY DATEPART(wk, trdate)
) AS cte
SELECT
weekno,
convert(varchar(10),DATEADD(dd, 1 - DATEPART(dw, date1), date1),111) startdate,
convert(varchar(10),DATEADD(dd, 7 - DATEPART(dw, date2), date2),111) enddate,
total_amount
from
(
SELECT
DATEPART(wk, trdate) weekno,
cast(min(trdate) as date) as date1,
cast(max(trdate) as date) as date2,
round(SUM(amount),2) AS total_amount
FROM <table>
GROUP BY DATEPART(wk, trdate)
) t
produces output like this (note: I added some data of my own to test a couple of edge cases).
Neither OP's query, nor any of the answers so far restrict the data by year, and they group only by week#. Thus if data from multiple years are included, you will still only get 53 rows, and each row will contain the aggregate data from all years in the data for that week. The start and end dates will then overlap and look strange. You could add additional grouping by year to further divide this, but the simplest fix would be to restrict the data to a single year, with a WHERE clause just prior to the GROUP BY clause, eg:
WHERE trdate >= '2018/01/01' and trdate < '2019/01/01'
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.