SQL 随时间的条件聚合
SQL conditional aggregation over time
出于报告目的,我正在努力获取一些 table 格式,以便在报告工具 (SSRS) 中轻松分组和聚合。
我使用SQL Server 2014
我有以下 table:
(示例中显示了日期,但这些实际上是日期时间)
tblEvents
datetimestamp prio
----------------------------------
2018-05-20 4
2018-08-05 1
2018-11-12 3
2018-11-13 1
需要 'resampled' 到 tblCalendar,这是一个等间隔的时间间隔 table,可配置 @start_datetime、@end_date、@number_of_intervals ,我已经设法用 CTE 做到了:
tblCalendar
datefrom dateto
----------------------------------
1900-01-01 2018-04-12
2018-04-12 2018-05-31
2018-05-31 2018-07-19
2018-07-19 2018-09-06
2018-09-06 2018-10-25
2018-10-25 2018-12-13
2018-12-13 2100-01-01
期望的结果是:
datefrom dateto prio
-------------------------------------------
1900-01-01 2018-04-12 -1
2018-04-12 2018-05-31 4
2018-05-31 2018-07-19 4
2018-07-19 2018-09-06 1
2018-09-06 2018-10-25 1
2018-10-25 2018-12-13 3
2018-12-13 2100-01-01 3
对于每个 tblCalendar 行,需要根据以下内容添加列优先级:
IF between [datefrom] en [dateto] 1 or more datetimestamp present in tblEvents
take MAXIMUM of prio's between [datefrom] en [dateto]
ELSE
IF before [date1] 1 or more datetimestamp present in tblEvents
take LAST prio between [datefrom] en [dateto]
ELSE
IF after [date2] 1 or more datetimestamp present
take FIRST prio between [datefrom] en [dateto]
ELSE
prio unknown = -1
END
END
END
所以我会将问题描述为条件聚合。
我是 SQL 的新手,我尝试用子查询、条件连接等来解决这个问题,但无法正常工作。下面的代码是我目前的尝试。
SELECT
datefrom,
dateto,
MAX(Case
When ((datetimestamp >= datefrom) AND (datetimestamp <= dateto)) Then prio
When ((datetimestamp <= datefrom)) Then 'last-known-prio'
When ((datetimestamp > dateto)) Then 'first future-prio'
Else
-1 -- no prio known ever
End),
FROM tblCalendar CROSS JOIN tblEvents
任何帮助和想法将不胜感激。
这不是条件聚合。
这是来自您的 tblCalendar
的简单 select,然后是基于 CASE 的 SUBSELECT 以获得 prio
值。
伪代码:
SELECT
datefrom,
dateto,
CASE
WHEN {between [datefrom] en [dateto] 1 or more datetimestamp present in tblEvents}
THEN (SELECT {MAXIMUM of prio's between [datefrom] en [dateto]})
WHEN {before [date1] 1 or more datetimestamp present in tblEvents}
THEN (SELECT {LAST prio between [datefrom] en [dateto]})
WHEN {after [date2] 1 or more datetimestamp present}
THEN (SELECT {FIRST prio between [datefrom] en [dateto]})
ELSE -1
END as prio
FROM tblCalendar
CROSS APPLY 等可能还有其他语法选项,但这是思考这个问题的方式。
出于报告目的,我正在努力获取一些 table 格式,以便在报告工具 (SSRS) 中轻松分组和聚合。
我使用SQL Server 2014
我有以下 table: (示例中显示了日期,但这些实际上是日期时间)
tblEvents
datetimestamp prio
----------------------------------
2018-05-20 4
2018-08-05 1
2018-11-12 3
2018-11-13 1
需要 'resampled' 到 tblCalendar,这是一个等间隔的时间间隔 table,可配置 @start_datetime、@end_date、@number_of_intervals ,我已经设法用 CTE 做到了:
tblCalendar
datefrom dateto
----------------------------------
1900-01-01 2018-04-12
2018-04-12 2018-05-31
2018-05-31 2018-07-19
2018-07-19 2018-09-06
2018-09-06 2018-10-25
2018-10-25 2018-12-13
2018-12-13 2100-01-01
期望的结果是:
datefrom dateto prio
-------------------------------------------
1900-01-01 2018-04-12 -1
2018-04-12 2018-05-31 4
2018-05-31 2018-07-19 4
2018-07-19 2018-09-06 1
2018-09-06 2018-10-25 1
2018-10-25 2018-12-13 3
2018-12-13 2100-01-01 3
对于每个 tblCalendar 行,需要根据以下内容添加列优先级:
IF between [datefrom] en [dateto] 1 or more datetimestamp present in tblEvents
take MAXIMUM of prio's between [datefrom] en [dateto]
ELSE
IF before [date1] 1 or more datetimestamp present in tblEvents
take LAST prio between [datefrom] en [dateto]
ELSE
IF after [date2] 1 or more datetimestamp present
take FIRST prio between [datefrom] en [dateto]
ELSE
prio unknown = -1
END
END
END
所以我会将问题描述为条件聚合。
我是 SQL 的新手,我尝试用子查询、条件连接等来解决这个问题,但无法正常工作。下面的代码是我目前的尝试。
SELECT
datefrom,
dateto,
MAX(Case
When ((datetimestamp >= datefrom) AND (datetimestamp <= dateto)) Then prio
When ((datetimestamp <= datefrom)) Then 'last-known-prio'
When ((datetimestamp > dateto)) Then 'first future-prio'
Else
-1 -- no prio known ever
End),
FROM tblCalendar CROSS JOIN tblEvents
任何帮助和想法将不胜感激。
这不是条件聚合。
这是来自您的 tblCalendar
的简单 select,然后是基于 CASE 的 SUBSELECT 以获得 prio
值。
伪代码:
SELECT
datefrom,
dateto,
CASE
WHEN {between [datefrom] en [dateto] 1 or more datetimestamp present in tblEvents}
THEN (SELECT {MAXIMUM of prio's between [datefrom] en [dateto]})
WHEN {before [date1] 1 or more datetimestamp present in tblEvents}
THEN (SELECT {LAST prio between [datefrom] en [dateto]})
WHEN {after [date2] 1 or more datetimestamp present}
THEN (SELECT {FIRST prio between [datefrom] en [dateto]})
ELSE -1
END as prio
FROM tblCalendar
CROSS APPLY 等可能还有其他语法选项,但这是思考这个问题的方式。