求供给种类相同的供应商

有一个供应商表结构如下:

create table tb_vender(
    id number(4,0) not null primary key,
    vendername nvarchar2(20) not null,
    part nvarchar2(20) not null)

充值数据:

复制代码
insert into tb_vender(id,vendername,part) values('1','创新','cover');
insert into tb_vender(id,vendername,part) values('2','创新','box');
insert into tb_vender(id,vendername,part) values('3','创新','knife');
insert into tb_vender(id,vendername,part) values('4','日立','box');
insert into tb_vender(id,vendername,part) values('5','日立','knife');
insert into tb_vender(id,vendername,part) values('6','渤海','knife');
insert into tb_vender(id,vendername,part) values('7','渤海','box');
insert into tb_vender(id,vendername,part) values('8','渤海','cover');
insert into tb_vender(id,vendername,part) values('9','东风','box');
insert into tb_vender(id,vendername,part) values('10','东风','knife');
insert into tb_vender(id,vendername,part) values('11','益达日平','knife');
insert into tb_vender(id,vendername,part) values('12','益达日平','box');
insert into tb_vender(id,vendername,part) values('13','红日','box');
insert into tb_vender(id,vendername,part) values('14','红日','cover');
复制代码

充值后数据如下:

复制代码
SQL> select * from tb_vender;

        ID VENDERNAME                               PART
---------- ---------------------------------------- ----------------------------------------
         1 创新                                     cover
         2 创新                                     box
         3 创新                                     knife
         4 日立                                     box
         5 日立                                     knife
         6 渤海                                     knife
         7 渤海                                     box
         8 渤海                                     cover
         9 东风                                     box
        10 东风                                     knife
        11 益达日平                                 knife
        12 益达日平                                 box
        13 红日                                     box
        14 红日                                     cover

已选择14行。
复制代码

需求出来了,那就是求供应品种相同的供应商,如创新-渤海,日立-东风等。

有了listagg的帮助,将分组内零件名连接起来不是难事,于是有了下面的SQL:

select vendername as vname,listagg(part,',') within group(order by part) as parts from tb_vender group by vendername

这样的数据直接做自联结会出现A-B,B-A的重复情况,于是给它加一列序号。

select tbv.*,rownum as rn from (select vendername as vname,listagg(part,',') within group(order by part) as parts from tb_vender group by vendername) tbv

有了上面的SQL,就可以做自联结了:

select a.*,b.* from 
(select tbv.*,rownum as rn from (select vendername as vname,listagg(part,',') within group(order by part) as parts from tb_vender group by vendername) tbv) a
inner join
(select tbv.*,rownum as rn from (select vendername as vname,listagg(part,',') within group(order by part) as parts from tb_vender group by vendername) tbv) b
on a.parts=b.parts
where a.vname<>b.vname and a.rn<b.rn

上面的SQL中,a.parts=b.parts满足了零件种类个数相同就进行匹配的需求,但这样的数据会有自己和自己连接的情况,因此需要a.vname<>b.vname过滤一次,还有 诸如东风连到日立,后来又有日立连到东风的重复情况,这时就需要a.rn<b,rn确保连接过了的不再连接。

注意on里放连接条件,where里放筛选条件,这样比较清晰易懂。

--2020年3月29日--

上文使用到的全部SQL:

复制代码
create table tb_vender(
    id number(4,0) not null primary key,
    vendername nvarchar2(20) not null,
    part nvarchar2(20) not null)
    
    

insert into tb_vender(id,vendername,part) values('1','创新','cover');
insert into tb_vender(id,vendername,part) values('2','创新','box');
insert into tb_vender(id,vendername,part) values('3','创新','knife');
insert into tb_vender(id,vendername,part) values('4','日立','box');
insert into tb_vender(id,vendername,part) values('5','日立','knife');
insert into tb_vender(id,vendername,part) values('6','渤海','knife');
insert into tb_vender(id,vendername,part) values('7','渤海','box');
insert into tb_vender(id,vendername,part) values('8','渤海','cover');
insert into tb_vender(id,vendername,part) values('9','东风','box');
insert into tb_vender(id,vendername,part) values('10','东风','knife');
insert into tb_vender(id,vendername,part) values('11','益达日平','knife');
insert into tb_vender(id,vendername,part) values('12','益达日平','box');
insert into tb_vender(id,vendername,part) values('13','红日','box');
insert into tb_vender(id,vendername,part) values('14','红日','cover');


select * from tb_vender

select vendername,count(*) from tb_vender group by vendername

select vendername as vname,listagg(part,',') within group(order by part) as parts from tb_vender group by vendername

select tbv.*,rownum as rn from (select vendername as vname,listagg(part,',') within group(order by part) as parts from tb_vender group by vendername) tbv

select a.* from 
(select tbv.*,rownum as rn from (select vendername as vname,listagg(part,',') within group(order by part) as parts from tb_vender group by vendername) tbv) a

select a.*,b.* from 
(select tbv.*,rownum as rn from (select vendername as vname,listagg(part,',') within group(order by part) as parts from tb_vender group by vendername) tbv) a
inner join
(select tbv.*,rownum as rn from (select vendername as vname,listagg(part,',') within group(order by part) as parts from tb_vender group by vendername) tbv) b
on a.parts=b.parts
where a.vname<>b.vname and a.rn<b.rn
复制代码

 

posted @   逆火狂飙  阅读(200)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
历史上的今天:
2018-03-29 【pyhon】nvshens图片批量下载爬虫1.01
2018-03-29 【pyhon】Python里的字符串查找函数find和java,js里的indexOf相似,找到返回序号,找不到返回-1
2018-03-29 【pyhon】nvshens图片批量下载爬虫
2018-03-29 【python】下载网络文件到本地
2018-03-29 【python】列出http://www.cnblogs.com/xiandedanteng中所有博文的标题
2018-03-29 【Python爬虫】将某网页中的表格里的十六进制颜色值转换成十进制,再生成新表格
2018-03-29 【python】如何安装requests
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东
点击右上角即可分享
微信分享提示