1

对于下表,我们如何找到名称连续出现 3 次的客户。

+---------+-----------+
| CUST_ID | CUST_NAME |
+---------+-----------+
| 1       | SAM       |
+---------+-----------+
| 2       | SAM       |
+---------+-----------+
| 3       | SAM       |
+---------+-----------+
| 4       | PETER     |
+---------+-----------+
| 5       | PETER     |
+---------+-----------+

Desired_Output

+-----------+
| CUST_NAME |
+-----------+
| SAM       |
+-----------+

表定义:

create table Customer
(
  cust_id int,
  cust_name varchar2(20)
);

insert into customer values (1, 'SAM');
insert into customer values (2, 'SAM');
insert into customer values (3, 'SAM');
insert into customer values (4, 'PETER');
insert into customer values (5, 'PETER');

到目前为止尝试过的代码

Select distinct cust_name from (
select
cust_id,
cust_name,
lag(cust_name,1,0) over (order by cust_id)  as prev_cust_name,
lead(cust_name,1,0) over (order by cust_id) as next_cust_name
 from customer) a
 where a.prev_cust_name=a.next_cust_name;

我相信我们可以通过使用领先/滞后来获得上一行和下一行来做到这一点。尽管我的解决方案提供了所需的输出,但我认为这不是正确的解决方案。

4

2 回答 2

2

你的方法很接近。你还需要一个比较:

select distinct cust_name 
from (select c.*
             lag(cust_name) over (order by cust_id)  as prev_cust_name,
             lead(cust_name) over (order by cust_id) as next_cust_name
      from customer c
     ) a c
where prev_cust_name = cust_name and cust_name = next_cust_name;

对于更通用的解决方案,您可以比较两个滞后:

select distinct cust_name 
from (select c.*
             lag(cust_id, 2) over (order by cust_id)  as prev2_cust_id,
             lag(cust_id, 2) over (partitioin by name order by cust_id)  as prev2_cust_id_name
      from customer c
     ) a c
where prev2_cust_id = prev2_cust_id_name;

这看起来有两行 - 一次cust_id仅用于名称,一次仅用于名称。如果cust_id值相同,则所有行都具有相同的名称。您可以调整2到任何值。

于 2020-08-26T18:39:11.063 回答
1

如果要查找N连续值,可以使用窗口函数。请参见 N = 4 的示例:

with params (n) as (select 4 from dual) -- Set N = 4
select distinct cust_name
from (
  select
    cust_id, cust_name, n,
    min(cust_name) over 
      (order by cust_id rows between n - 1 preceding and current row) as mi,
    max(cust_name) over
      (order by cust_id rows between n - 1 preceding and current row) as ma,
    count(*) over
      (order by cust_id rows between n - 1 preceding and current row) as cnt
  from customer
  cross join params
) x
where mi = ma and cnt = n

请参阅SQL Fiddle上的运行示例。

于 2020-08-26T20:52:28.863 回答