使用SQL Server或Vertica将按日期范围的记录转换为按天/月的记录
我可以使用SQL Server或Vertica作为数据库,使用Tableau作为报告工具。任何一种介质中的溶液都会有帮助 数据资源: 我有一个包含100条记录的表(userActivity),结构为:User、StartDate、EndDate 需要: 我感兴趣的是按天和月编制显示“总活动天数”的报告,这意味着如果User1的范围为“20180101”到“20180331”,则他们将在1月、2月和3月的每一天贡献一天,或者如果按月合计,则为31、28和31天 目标: 我最终会将所有用户的总活动天数汇总为输出,以实现每天/每月的单个总活动天数 此报告将持续到永久,因此我更喜欢不按天/月硬编码CASE/IF-THEN语句的解决方案 谢谢 解决方案:使用SQL Server或Vertica将按日期范围的记录转换为按天/月的记录,sql,sql-server,tsql,tableau-api,vertica,Sql,Sql Server,Tsql,Tableau Api,Vertica,我可以使用SQL Server或Vertica作为数据库,使用Tableau作为报告工具。任何一种介质中的溶液都会有帮助 数据资源: 我有一个包含100条记录的表(userActivity),结构为:User、StartDate、EndDate 需要: 我感兴趣的是按天和月编制显示“总活动天数”的报告,这意味着如果User1的范围为“20180101”到“20180331”,则他们将在1月、2月和3月的每一天贡献一天,或者如果按月合计,则为31、28和31天 目标: 我最终会将所有用户的总活动天
WITH base AS (
SELECT
User AS u
,StartDate AS s
,EndDate AS e
,DATEDIFF(
dd,
StartDate,
EndDate
)+1 AS d
FROM userActivity
),
recurse AS (
SELECT u, s, e, d, x=(d-1)
FROM base
UNION ALL
SELECT u, s, e, d, x-1 AS x
FROM recurse
WHERE x>0
)
SELECT u, DATEADD(dd, x, s) AS recordperday
FROM recurse
ORDER BY u, recordperday
--Extends SQL Server's recursion limit
OPTION (MAXRECURSION 500)
尽管递归CTE是这种场景的一个很好的候选者,但它可以单独使用tableau来处理。假设您有这些数据,下面是生成视图所需的步骤
使用Vertica-它有TIMESERIES子句-不需要递归 我将尝试下面的方法,并检查常用表表达式的中间结果,看看它是如何工作的
WITH
-- two test rows ....
input(uid,start_dt,end_dt) AS (
SELECT 1,DATE '2018-01-01', DATE '2018-03-31'
UNION ALL SELECT 2,DATE '2018-02-01', DATE '2018-04-01'
)
,
-- set the stage for Vertica's TIMESERIES clause
-- note: TIMESERIES relies on timestamps ...
limits(uid,lim_dt,qty) AS (
SELECT
uid
, start_dt::TIMESTAMP
, 1
FROM input
UNION ALL
SELECT
uid
, end_dt::TIMESTAMP
, 1
FROM input
)
,
-- apply the Vertica TIMESERIES clause
counters AS (
SELECT
uid
, act_dt
, TS_FIRST_VALUE(qty) AS qty
FROM limits
TIMESERIES act_dt AS '1 DAY' OVER(PARTITION BY uid ORDER BY lim_dt)
)
SELECT
uid
, MONTH(act_dt) AS activity_month
, SUM(qty)
FROM counters
GROUP BY 1,2;
-- out uid | activity_month | sum
-- out -----+----------------+-----
-- out 1 | 1 | 31
-- out 1 | 2 | 28
-- out 1 | 3 | 31
-- out 2 | 2 | 28
-- out 2 | 3 | 31
-- out 2 | 4 | 1
-- out (6 rows)
-- out
-- out time: first fetch (6 rows): 120.515 ms. all rows formatted: 120.627 ms
我相信我已经弄明白了!:)我使用以下代码创建一个最终表,每个用户在每个活动日有一条记录。然后,我将在表格中按天或按月计算这些数字。请看下面。优秀的Vertica解决方案。我喜欢根据后端要求提供选项。在很多情况下,我也更喜欢使用Vertica。做得好!我假设有一个Tableau解决方案,但对我来说,Tableau的大部分内容仍然非常复杂。感谢您阐明此功能,Jose!顺便说一句,爱的详细描述@AndrewGlenn,很高兴这有帮助。这是一个很好的问题,我很喜欢回答它。虽然第一个解决方案对我来说是可行的(也是我设计的),但这个方案显然比其他方案要差,假设可以使用Tableau或Vertica。此外,如果数据集或数据源比我的更大或更复杂,我的SQL Server解决方案可能会面临挑战。到目前为止,我们有3个可行的选择!