oracle:计算连续行中状态的出现次数
oracle: Count occurrence of a status in consecutive rows
我有一个 table,它在 oracle 中存储客户回复的状态。我必须计算客户最后一次连续拒绝的次数。
例如:
ID 状态
----------------------------
1. 拒绝
2. 已接受
3. 拒绝
4. 拒绝
这将有计数 = 2。
因为最后两个被拒绝了。
注意:原始发布者在 "comment" 中澄清说她需要不同的要求 - 在单独的答复中解决它。保留这个,因为它显示了一种可能的解决方案,可以解决比 OP 更复杂的问题。
假设您想要最近连续 "Declines" 的计数(即使后面跟着 "Accepted" - 并且您希望允许多个客户 - 这是一种可能的解决方案。
输入table(我叫它"t"):
SQL> select * from t;
CUSTOMER_ID DECISION_ID STATUS
----------- ----------- --------------------
10 1 Accepted
10 2 Declined
10 3 Declined
10 4 Accepted
10 5 Accepted
10 6 Declined
10 7 Declined
30 1 Declined
30 2 Accepted
30 3 Declined
30 4 Accepted
30 5 Declined
30 6 Declined
30 7 Declined
30 8 Accepted
30 9 Accepted
查询:
with t1 as
(
select customer_id,
decision_id - row_number() over
(partition by customer_id order by decision_id) as idx
from t
where status = 'Declined'
),
t2 as (select customer_id, max(idx) as max_idx from t1 group by customer_id)
select t1.customer_id, count(1) as ct
from t1 join t2 on t1.customer_id = t2.customer_id
where t1.idx = t2.max_idx
group by t1.customer_id
order by t1.customer_id
/
查询输出:
CUSTOMER_ID CT
----------- ----------
10 2
30 3
@Gurmeet - 那么问题就简单多了。这是解决它的一种方法。如果您需要 customer_id 排序的结果,请在最后添加 order by customer_id
。如果客户从未有过 "Accepted" 状态的交易,则需要 CTE t2 中 d_A 定义中的 nvl。
输入:与我的另一个答案相同。
查询:(已修改以满足 OP 附加要求):
with t0 as (select customer_id, status, row_number() over
(partition by customer_id order by decision_id) rn from t),
t1 as (select customer_id, max(rn) as d_all from t0 group by customer_id),
t2 as (select customer_id, nvl(max(rn), 0) as d_A from t0
where status = 'Accept' group by customer_id)
select customer_id, d_all - d_A as ct from t1 natural join t2
/
结果:
CUSTOMER_ID CT
----------- ----------
30 0
10 2
2 rows selected.
我有一个 table,它在 oracle 中存储客户回复的状态。我必须计算客户最后一次连续拒绝的次数。
例如:
ID 状态
----------------------------
1. 拒绝
2. 已接受
3. 拒绝
4. 拒绝
这将有计数 = 2。
因为最后两个被拒绝了。
注意:原始发布者在 "comment" 中澄清说她需要不同的要求 - 在单独的答复中解决它。保留这个,因为它显示了一种可能的解决方案,可以解决比 OP 更复杂的问题。
假设您想要最近连续 "Declines" 的计数(即使后面跟着 "Accepted" - 并且您希望允许多个客户 - 这是一种可能的解决方案。
输入table(我叫它"t"):
SQL> select * from t;
CUSTOMER_ID DECISION_ID STATUS
----------- ----------- --------------------
10 1 Accepted
10 2 Declined
10 3 Declined
10 4 Accepted
10 5 Accepted
10 6 Declined
10 7 Declined
30 1 Declined
30 2 Accepted
30 3 Declined
30 4 Accepted
30 5 Declined
30 6 Declined
30 7 Declined
30 8 Accepted
30 9 Accepted
查询:
with t1 as
(
select customer_id,
decision_id - row_number() over
(partition by customer_id order by decision_id) as idx
from t
where status = 'Declined'
),
t2 as (select customer_id, max(idx) as max_idx from t1 group by customer_id)
select t1.customer_id, count(1) as ct
from t1 join t2 on t1.customer_id = t2.customer_id
where t1.idx = t2.max_idx
group by t1.customer_id
order by t1.customer_id
/
查询输出:
CUSTOMER_ID CT
----------- ----------
10 2
30 3
@Gurmeet - 那么问题就简单多了。这是解决它的一种方法。如果您需要 customer_id 排序的结果,请在最后添加 order by customer_id
。如果客户从未有过 "Accepted" 状态的交易,则需要 CTE t2 中 d_A 定义中的 nvl。
输入:与我的另一个答案相同。
查询:(已修改以满足 OP 附加要求):
with t0 as (select customer_id, status, row_number() over
(partition by customer_id order by decision_id) rn from t),
t1 as (select customer_id, max(rn) as d_all from t0 group by customer_id),
t2 as (select customer_id, nvl(max(rn), 0) as d_A from t0
where status = 'Accept' group by customer_id)
select customer_id, d_all - d_A as ct from t1 natural join t2
/
结果:
CUSTOMER_ID CT
----------- ----------
30 0
10 2
2 rows selected.