我有一个表,其中提供了有关哪些用户购买了软件包,软件包何时启动,过期等信息。
表:
+------+--------------+------------+------------+---------+
| user | Package_Type | Start | End | Status |
+------+--------------+------------+------------+---------+
| 111 | A | 2019-06-01 | 2019-06-18 | Valid |
| 123 | A | 2019-06-01 | 2019-06-18 | Valid |
| 124 | A | 2019-06-02 | 2019-06-06 | Expired | //Type A expired
| 124 | C | 2019-06-02 | 2019-06-18 | Valid |
| 125 | B | 2019-06-03 | 2019-06-09 | Expired |
| 126 | B | 2019-06-04 | 2019-06-20 | Valid |
| 127 | B | 2019-06-04 | 2019-06-07 | Expired | // Type B expired
| 124 | B | 2019-06-06 | 2019-06-18 | Valid | //Renewal to type B after expiry of type A
| 127 | B | 2019-06-08 | 2019-06-18 | Valid | // Renwal to Type B
+------+--------------+------------+------------+---------+
在一个时间范围(将时间范围设为WHERE start BETWEEN '2019-06-01' AND '2019-06-10'
)中,我想知道有多少用户的软件包过期了。
预期输出如下
+------------+---------+---------+
| Date | Expired | Renewed |
+------------+---------+---------+
| 2019-06-01 | 0 | 0 |
| 2019-06-02 | 0 | 0 |
| 2019-06-03 | 0 | 0 |
| 2019-06-04 | 0 | 0 |
| 2019-06-05 | 0 | 0 |
| 2019-06-06 | 1 | 1 | // Expiry and renewal of user 124
| 2019-06-07 | 1 | 0 | // Expiry of user 127
| 2019-06-08 | 0 | 1 |// Renewal of user 127
| 2019-06-09 | 1 | 0 |// Expiry of user 125
| 2019-06-10 | 0 | 0 |
+------------+---------+---------+
用户不必续签相同类型的软件包。
更新1 我还希望将以上数据表示为
+--------------+---------+---------+
| Package_Type | Expired | Renewed |
+--------------+---------+---------+
| A | 1 | 0 |
| B | 2 | 2 |
| C | 0 | 0 |
+--------------+---------+---------+
我想要一个查询,如果我更改
WHERE start BETWEEN '2019-06-01' AND '2019-06-10'
)*
上表将根据start
过滤器进行更新
答案 0 :(得分:1)
您可以使用累积的max()
来获取续订的用户:
select t1.*,
(case when max(case when status = 'expired' then [start] end) over (partition by user order by [start]) < [start] and
status = 'Valid'
then 1 else 0
end) as renewed
from table1 t1;
然后您可以使用此信息来汇总数据。但是,这种总结是相当棘手的。续订是在开始日期算起的,而到期是在到期日期。为了解决这个问题,它使用apply
取消数据透视。
select dte, sum(is_expire), sum(is_renew)
from (select t1.*,
(case when max(case when status = 'expired' then [start] end) over (partition by user order by [start]) < start and
status = 'Valid'
then 1 else 0
end) as renewed
from table1 t1
) t1 cross apply
(values (start, 0, renewed),
([end], case when status = 'expired' then 1 else 0 end, 0)
) v(dte, is_expire, is_renew)
group by dte
order by dte;
Here是一个SQLFiddle。