我可以使用SQL Server或Vertica作为数据库,使用Tableau作为报告工具。在这些媒介中的任何一种解决方案都是有帮助的。
数据资源: 我有一个包含100条记录的表(userActivity),其结构为:User,StartDate,EndDate
需要: 我有兴趣按日期和月份准备显示“活动总天数”的报告,这意味着,如果User1的范围从“ 20180101”到“ 20180331”,则他们将在1月,2月和3月的每一天贡献一天,或31如果按月汇总则为28天和31天。
目标: 最终,我将所有用户的总活动天数汇总为输出,以实现每天/每月的总计。
此报告将涉及永久性,所以我希望解决方案不要按日/月对CASE / IF-THEN语句进行硬编码。
谢谢!
答案 0 :(得分:2)
尽管递归CTE是此方案的理想选择,但可以单独使用tableau进行处理。假设您拥有这些数据,下面是生成视图所需的步骤。
您需要两列日期完全相同的表,因为Tableau不允许同一列上有多个连接条件。
答案 1 :(得分:2)
使用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
答案 2 :(得分:0)
解决方案:
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)