Группировка sql строк по неделям - PullRequest
0 голосов
/ 27 января 2020

У меня есть таблица

DATE        Val
01-01-2020  1
01-02-2020  3
01-05-2020  2
01-07-2020  8
01-13-2020  3
...

Я хочу суммировать эти значения к после воскресенья. Например, в приведенном выше примере:

1-05-2020, 1-12-2020 и 1-19-2020 - воскресенья, поэтому я хочу суммировать их по этим датам.

Окончательный результат должен выглядеть примерно так:

DATE       SUM
1-05-2020  6    //(01-01-2020 + 01-02-2020 + 01-05-2020)
1-12-2020  8
1-19-2020  3

Я не был уверен, что лучше всего начать с создания таблицы временного календаря, а затем попытаться присоединиться в обратном направлении на основе который? Или если бы был более простой способ задействовать DATEDIFF. Любая помощь будет оценена! Спасибо!

Ответы [ 3 ]

2 голосов
/ 28 января 2020

Вот решение, которое использует DATEADD & DATEPART для вычисления ближайшего воскресенья.

С поправкой на другую настройку @@datefirst.
(Поскольку значения дня недели в части даты отличаются в зависимости от настройки DATEFIRST)

Пример данных:

create table #TestTable
(
  Id int identity(1,1) primary key,
  [Date] date,
  Val int
);

insert into #TestTable
 ([Date], Val)
 VALUES
  ('2020-01-01', 1)
, ('2020-01-02', 3)
, ('2020-01-05', 2)
, ('2020-01-07', 8)
, ('2020-01-13', 3)
;

Запрос:

WITH CTE_DATA AS
(
  SELECT [Date], Val
  , DATEADD(day, 
     ((7-(@@datefirst+datepart(weekday, [Date])-1)%7)%7),
     [Date]) AS Sunday
  FROM #TestTable
)
SELECT 
Sunday AS [Date],
SUM(Val) AS [Sum]
FROM CTE_DATA
GROUP BY Sunday
ORDER BY Sunday;
Date       | Sum
:--------- | --:
2020-01-05 |   6
2020-01-12 |   8
2020-01-19 |   3

db <> fiddle здесь

Дополнительно:

Очевидно, хитрость добавления разницы недель от дня 0 до дня 6 также работает независимо от настройки DATEFIRST.
Таким образом, этот запрос вернет тот же результат для данных примера.

WITH CTE_DATA AS
(
  SELECT [Date], Val
  , CAST(DATEADD(week, DATEDIFF(week, 0, DATEADD(day, -1, [Date])), 6) AS DATE) AS Sunday
  FROM #TestTable
)
SELECT
Sunday AS [Date],
SUM(Val) AS [Sum]
FROM CTE_DATA
GROUP BY Sunday
ORDER BY Sunday;

Вычитание 1 дня гарантирует, что если дата уже воскресенье, то она не рассчитывается до следующего воскресенья.

0 голосов
/ 27 января 2020

Вот простое решение. Помещение ваших значений во временную таблицу и просмотр результатов в этой таблице:

DECLARE @dates TABLE
(
    mDATE DATE,
    Val INT,
    Sunday DATE
)

INSERT INTO @dates (mDATE,Val) VALUES
('01-01-2020',1),('01-02-2020',3),('01-05-2020',2),('01-07-2020',8),('01-13-2020',3)

UPDATE @dates
SET Sunday = dateadd(week, datediff(week, 0, mDATE), 6)

SELECT Sunday,SUM(Val) AS Val FROM @dates
GROUP BY Sunday

ВЫХОД:

Sunday      Val
2020-01-05  4
2020-01-12  10
2020-01-19  3
0 голосов
/ 27 января 2020

Вот способ сделать это: nb: 1-13-2020 не будет показывать, потому что это не воскресенье

with cte as
(        
select cast('01-01-2020'as Date) as Date,  1 as Val
union select '01-02-2020' , 3
union select '01-05-2020' , 2
union select '01-07-2020' , 8
)

select Date, max(dateadd(dd,number,Date)), sum(distinct Val) as SUM
from master..spt_values a inner join cte on Date <= dateadd(dd,number,Date) 
where type = 'p'
and year(dateadd(dd,number,Date))=year(Date)
and DATEPART(dw,dateadd(dd,number,Date)) = 7 
group by Date 

Вывод:

Date    (No column name)    SUM
2020-01-01  2020-12-26       1
2020-01-02  2020-12-26       3
2020-01-05  2020-12-26       2
2020-01-07  2020-12-26       8
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...