数据仓库查询以查找日期差距
Data Warehouse Query to find gap in dates
我有以下结果集
+----+----------------+--------------+----------------+-------------------+----------------+------------+-------------+------------+
| ID | row_start_date | row_end_date | terminate_date | termDateWasMember | dropped_reason | join_date | rejoin_date | renew_date |
+----+----------------+--------------+----------------+-------------------+----------------+------------+-------------+------------+
| 1 | 12-31-2016 | 02-03-2017 | NULL | Member | NULL | 08-08-2016 | NULL | 08-08-2016 |
+----+----------------+--------------+----------------+-------------------+----------------+------------+-------------+------------+
| 1 | 2-4-2016 | 2-14-2017 | NULL | Member | NULL | 08-08-2016 | NULL | 08-08-2016 |
+----+----------------+--------------+----------------+-------------------+----------------+------------+-------------+------------+
| 1 | 2-15-2017 | 2-21-2017 | 2-15-2016 | NonMember | DuesPayment | 08-08-2016 | NULL | 08-08-2016 |
+----+----------------+--------------+----------------+-------------------+----------------+------------+-------------+------------+
| 1 | 2-22-2017 | 12-31-9999 | NULL | Member | DuesPayment | 08-08-2016 | 2-22-2016 | 08-08-2016 |
+----+----------------+--------------+----------------+-------------------+----------------+------------+-------------+------------+
我想要完成的是创建一份报告或其他东西,以显示该人(在本例中是一个人,在 DW 中是许多人)在一行中他们是成员直到(终止日期)然后 post 终止他们再次加入的日期。因此,如果鲍勃是 2016 年 8 月 8 日的会员,并于 2017 年 2 月 15 日终止会员资格,然后支付会费并于 2017 年 2 月 22 日重新加入,我想表明鲍勃是 2016 年 8 月 8 日终止的会员,并且重新加入。
我正在尝试弄清楚是否有办法做到这一点。我想尝试在代码中执行此操作。
交付工具可以是 PowerBI、Excel 2016、Tableau SSRS
这是我正在使用的现有代码
SELECT m.id AS ID ,
CONVERT(CHAR(10),m.row_start_date,110) AS row_start_date ,
CONVERT(CHAR(10),m.row_end_date ,110) AS row_end_date,
CONVERT(CHAR(10),m.terminate_date,110) AS terminate_date ,
CASE WHEN m.terminate_date IS NULL THEN 'Member' ELSE 'Non-Member' END AS termDateWasMember,
m.dropped_reason ,
CONVERT(CHAR(10),join_date,110) AS join_date ,
CONVERT(CHAR(10),rejoin_date,110) AS rejoin_date ,
CONVERT(CHAR(10),renew_date,110) AS renew_date
FROM dim_membership m
INNER JOIN dim_individual i ON m.id = i.id
WHERE m.source_bk IN (
SELECT m.source_bk
FROM dim_membership m
INNER JOIN
( SELECT source_bk ,MIN(terminate_date) AS terminate_date
FROM dim_membership
GROUP BY source_bk
HAVING MIN(terminate_date) >= '02/15/2017'
) can ON m.source_bk = can.source_bk
WHERE row_is_current = 'Y')
AND m.row_start_date > '2010-12-31'
AND m.membership_level = 'National'
AND i.row_is_current = 'Y'
AND id = 9182039 --7236901 --9182039--= 9129028
ORDER BY m.source_bk ,
m.row_start_date,3 DESC
假设您可以查找 NonMember 行,然后查找 Member 行,我会添加一个 ROW_NUMBER OVER(PARTITION BY ID ORDER BY row_start_date) AS rownum
然后自连接,所以将您的查询放在顶部的 CTE 中:
WITH (your_query) AS model
SELECT m_term.terminate_date AS gap_start
,m_renew.rejoin_date AS gap_end
,m_term.*, m_renew.*
FROM model m_term
INNER JOIN model m_renew
ON m_renew.ID = m_term.ID
AND m_renew.rownum = m_term.rownum + 1
AND m_term.termDateWasMember = 'NonMember'
AND m_renew.termDateWasMember = 'Member';
所以它正在寻找从非成员到成员的转换,然后使用各个行中的日期字段来确定间隔。
我有以下结果集
+----+----------------+--------------+----------------+-------------------+----------------+------------+-------------+------------+
| ID | row_start_date | row_end_date | terminate_date | termDateWasMember | dropped_reason | join_date | rejoin_date | renew_date |
+----+----------------+--------------+----------------+-------------------+----------------+------------+-------------+------------+
| 1 | 12-31-2016 | 02-03-2017 | NULL | Member | NULL | 08-08-2016 | NULL | 08-08-2016 |
+----+----------------+--------------+----------------+-------------------+----------------+------------+-------------+------------+
| 1 | 2-4-2016 | 2-14-2017 | NULL | Member | NULL | 08-08-2016 | NULL | 08-08-2016 |
+----+----------------+--------------+----------------+-------------------+----------------+------------+-------------+------------+
| 1 | 2-15-2017 | 2-21-2017 | 2-15-2016 | NonMember | DuesPayment | 08-08-2016 | NULL | 08-08-2016 |
+----+----------------+--------------+----------------+-------------------+----------------+------------+-------------+------------+
| 1 | 2-22-2017 | 12-31-9999 | NULL | Member | DuesPayment | 08-08-2016 | 2-22-2016 | 08-08-2016 |
+----+----------------+--------------+----------------+-------------------+----------------+------------+-------------+------------+
我想要完成的是创建一份报告或其他东西,以显示该人(在本例中是一个人,在 DW 中是许多人)在一行中他们是成员直到(终止日期)然后 post 终止他们再次加入的日期。因此,如果鲍勃是 2016 年 8 月 8 日的会员,并于 2017 年 2 月 15 日终止会员资格,然后支付会费并于 2017 年 2 月 22 日重新加入,我想表明鲍勃是 2016 年 8 月 8 日终止的会员,并且重新加入。
我正在尝试弄清楚是否有办法做到这一点。我想尝试在代码中执行此操作。
交付工具可以是 PowerBI、Excel 2016、Tableau SSRS
这是我正在使用的现有代码
SELECT m.id AS ID ,
CONVERT(CHAR(10),m.row_start_date,110) AS row_start_date ,
CONVERT(CHAR(10),m.row_end_date ,110) AS row_end_date,
CONVERT(CHAR(10),m.terminate_date,110) AS terminate_date ,
CASE WHEN m.terminate_date IS NULL THEN 'Member' ELSE 'Non-Member' END AS termDateWasMember,
m.dropped_reason ,
CONVERT(CHAR(10),join_date,110) AS join_date ,
CONVERT(CHAR(10),rejoin_date,110) AS rejoin_date ,
CONVERT(CHAR(10),renew_date,110) AS renew_date
FROM dim_membership m
INNER JOIN dim_individual i ON m.id = i.id
WHERE m.source_bk IN (
SELECT m.source_bk
FROM dim_membership m
INNER JOIN
( SELECT source_bk ,MIN(terminate_date) AS terminate_date
FROM dim_membership
GROUP BY source_bk
HAVING MIN(terminate_date) >= '02/15/2017'
) can ON m.source_bk = can.source_bk
WHERE row_is_current = 'Y')
AND m.row_start_date > '2010-12-31'
AND m.membership_level = 'National'
AND i.row_is_current = 'Y'
AND id = 9182039 --7236901 --9182039--= 9129028
ORDER BY m.source_bk ,
m.row_start_date,3 DESC
假设您可以查找 NonMember 行,然后查找 Member 行,我会添加一个 ROW_NUMBER OVER(PARTITION BY ID ORDER BY row_start_date) AS rownum
然后自连接,所以将您的查询放在顶部的 CTE 中:
WITH (your_query) AS model
SELECT m_term.terminate_date AS gap_start
,m_renew.rejoin_date AS gap_end
,m_term.*, m_renew.*
FROM model m_term
INNER JOIN model m_renew
ON m_renew.ID = m_term.ID
AND m_renew.rownum = m_term.rownum + 1
AND m_term.termDateWasMember = 'NonMember'
AND m_renew.termDateWasMember = 'Member';
所以它正在寻找从非成员到成员的转换,然后使用各个行中的日期字段来确定间隔。