如何根据SQL中活动的开始和结束日期计算每天活动的数量

plupiseo  于 2022-10-22  发布在  其他
关注(0)|答案(2)|浏览(150)

我需要根据活动的开始和结束日期计算每天的活动数量

输入表格:

活动名称开始日期结束日期
活动A2022-07-102022-09-25
活动B2022-08-062022-10-07
活动C2022-07-302022-09-10
活动D2022-08-262022-10-24
活动E2022-07-172022-09-29
活动F2022-08-242022-09-12
活动G2022-08-112022-10-24
活动H2022-08-262022-11-22
活动I2022-08-292022-09-25
活动J2022-08-212022-11-15
活动K2022-07-202022-09-18
活动L2022-07-312022-11-20
活动M2022-08-172022-10-10
活动N2022-07-272022-09-07
活动O2022-07-292022-09-26
活动P2022-07-062022-09-15
活动Q2022-07-162022-09-22

不需要**(结果):**
|日期|计数唯一活动|
| ------------ | ------------ |
| 2022-07-02 | 17 |
| 2022-07-03 | 47 |
| 2022-07-04 | 5 |
| 2022-07-05 | 5 |
| 2022-07-06 | 25 |
| 2022-07-07 | 27 |
| 2022-07-08 | 17 |
| 2022-07-09 | 58 |
| 2022-07-10 | 23 |
| 2022-07-11 | 53 |
| 2022-07-12 | 18 |
| 2022-07-13 | 29 |
| 2022-07-14 | 52 |
| 2022-07-15 | 7 |
| 2022-07-16 | 17 |
| 2022-07-17 | 37 |
| 2022-07-18 | 33 |
我需要如何编写SQL命令才能获得上述结果?谢谢大家

nuypyhwy

nuypyhwy1#

在以下解决方案中,我们将string_split与复制结合使用,以生成新记录。

select   dt        as date
        ,count(*)  as Count_unique_campaigns

from      
(
select    *
         ,dateadd(day, row_number() over(partition by Campaign_name  order by (select null))-1, Start_date) as dt
from     (
         select   *
         from     t
         outer apply string_split(replicate(',',datediff(day, Start_date, End_date)),',')
         ) t
) t
group by dt
order by dt
日期Count_unique_campaigns
2022-07-061
2022-07-071
2022-07-081
2022-07-091
2022-07-102
2022-07-112
2022-07-122
2022-07-132
2022-07-142
2022-07-152
2022-07-163
2022-07-174
2022-07-184
2022-07-194
2022-07-205
2022-07-215
2022-07-225
2022-07-235
2022-07-245
2022-07-255
2022-07-265
2022-07-276
2022-07-286
2022-07-297
2022-07-308
2022-07-319
2022-08-019
2022-08-029
2022-08-039
2022-08-049
2022-08-059
2022-08-0610
2022-08-0710
2022-08-0810
2022-08-0910
2022-08-1010
2022-08-1111
2022-08-1211
2022-08-1311
2022-08-1411
2022-08-1511
2022-08-1611
2022-08-1712
2022-08-1812
2022-08-1912
2022-08-2012
2022-08-2113
2022-08-2213
2022-08-2313
2022-08-2414
2022-08-2514
2022-08-2616
2022-08-2716
2022-08-2816
2022-08-2917
2022-08-3017
2022-08-3117
2022-09-0117
2022-09-0217
2022-09-0317
2022-09-0417
2022-09-0517
2022-09-0617
2022-09-0717
2022-09-0816
2022-09-0916
2022-09-1016
2022-09-1115
2022-09-1215
2022-09-1314
2022-09-1414
2022-09-1514
2022-09-1613
2022-09-1713
2022-09-1813
2022-09-1912
2022-09-2012
2022-09-2112
2022-09-2212
2022-09-2311
2022-09-2411
2022-09-2511
2022-09-269
2022-09-278
2022-09-288
2022-09-298
2022-09-307
2022-10-017
2022-10-027
2022-10-037
2022-10-047
2022-10-057
2022-10-067
2022-10-077
2022-10-086
2022-10-096
2022-10-106
2022-10-115
2022-10-125
2022-10-135
2022-10-145
2022-10-155
2022-10-165
2022-10-175
2022-10-185
2022-10-195
2022-10-205
2022-10-215
2022-10-225
2022-10-235
2022-10-245
2022-10-253
2022-10-263
2022-10-273
2022-10-283
2022-10-293
2022-10-303
2022-10-313
2022-11-013
2022-11-023
2022-11-033
2022-11-043
2022-11-053
2022-11-063
2022-11-073
2022-11-083
2022-11-093
2022-11-103
2022-11-113
2022-11-123
2022-11-133
2022-11-143
2022-11-153
2022-11-162
2022-11-172
2022-11-182
2022-11-192
2022-11-202
2022-11-211
2022-11-221

对于Azure和SQL Server 2022中的SQL,我们有一个基于[ordinal][4]的更干净的解决方案。
“Azure SQL数据库、Azure SQL托管示例和Azure Synapse Analytics(仅限无服务器SQL池)当前支持enable_ordinal参数和ordinal输出列。从SQL Server 2022(16.x)预览版开始,SQL Server中提供了参数和输出列。”

select   dt        as date
        ,count(*)  as Count_unique_campaigns

from      
(
select    *
         ,dateadd(day, ordinal-1, Start_date) as dt
from     (
         select   *
         from     t
         outer apply string_split(replicate(',',datediff(day, Start_date, End_date)),',', 1)
         ) t
) t
group by dt
order by dt

Fiddle

gupuwyp2

gupuwyp22#

你的样本数据似乎与你想要的结果不符,但我认为你想要的是:

DECLARE @Start date, @End date;

-- first, find the earliest and last date:

SELECT @Start = MIN([Start date]), @End = MAX([End date])
  FROM dbo.Campaigns;

-- now use a recursive CTE to build a date range, 
-- and count the number of campaigns that have a row
-- where the campaign was active on that date:

WITH d(d) AS 
(
  SELECT @Start 
  UNION ALL 
  SELECT DATEADD(DAY, 1, d) FROM d WHERE d < @End
)
SELECT 
  [Date] = d, 
  [Count unique campaigns] = COUNT(*) 
FROM d 
INNER JOIN dbo.Campaigns AS c
ON d.d >= c.[Start date] AND d.d <= c.[End date]
GROUP BY d.d OPTION (MAXRECURSION 32767);

this fiddle中的工作示例。

相关问题