为数据组分配唯一的列表编号

时间:2017-03-27 13:53:54

标签: sql oracle plsql oracle10g

我正在使用oracle数据库10g。

我陷入了客户需求的一个逻辑实现中。

我们在table ::

中有以下数据
id  cust_nbr item_id    
---------------------
1       A       10 
2       A       11 
3       A       12 
4       B       10 
5       B       11 
6       B       12 
7       C       11 
8       C       12 
9       C       13 
10      C       14 

预期输出::

id  cust_nbr item_id    list_nbr
---------------------------------------
1       A       10      1
2       A       11      1
3       A       12      1
4       B       10      1
5       B       11      1
6       B       12      1
7       C       11      2
8       C       12      2
9       C       13      2
10      C       14      2

我们希望为拥有不同客户的所有相同项目分配唯一的清单编号。

正如您在此处所见,item_id 10,11,12被分配给2个客户(A,B),因此list_nbr 1被分配给该2个客户。 item_id 11,12,13,14仅分配给1个客户(C),因此list_nbr 2被分配给该客户。

我无法使用sql找到任何实现此更改的方法。

这个数据只是一个例子。这张表中将有数千条记录。

你能帮我解决这个问题吗?

感谢。

1 个答案:

答案 0 :(得分:0)

编辑:我离开了这个答案,但它适用于Oracle 11g,而不是10g。您可以尝试将listagg()替换为wm_concat(),但组中的order by对此解决方案非常重要。

一种方法是使用listagg()将值组合在一起,然后分配一个值。所以,顾客,这将是:

select cust_nbr, listagg(item_id, ',') within group (order by item_id) as items
from t
group by cust_nbr;

您可以使用dense_rank()分配唯一值:

select cust_nbr,
       listagg(item_id, ',') within group (order by item_id) as items,
       dense_rank() over (order by listagg(item_id, ',') within group (order by item_id)) as list_nbr
from t
group by cust_nbr;

然后,您可以将其加入到您的数据中:

with l as (
      select cust_nbr,
             listagg(item_id, ',') within group (order by item_id) as items,
             dense_rank() over (order by listagg(item_id, ',') within group (order by item_id)) as list_nbr
      from t
      group by cust_nbr
     )
select t.*, l.list_nbr
from t join
     l
     on t.cust_nbr = l.cust_nbr;