SQL技巧:WITH RECURSIVE递归运算
阅读原文时间:2023年08月25日阅读:8

SQL技巧:WITH RECURSIVE递归运算

-- 计算递归
WITH RECURSIVE t(n) AS (
    VALUES (1)
  UNION ALL
&nbsp;&nbsp;&nbsp;&nbsp;SELECT&nbsp;n+1&nbsp;FROM&nbsp;t&nbsp;WHERE&nbsp;n&nbsp;<&nbsp;100
)
SELECT&nbsp;sum(n)&nbsp;FROM&nbsp;t;

--&nbsp;测试工资递归
create&nbsp;table&nbsp;company&nbsp;(
&nbsp;&nbsp;&nbsp;&nbsp;id&nbsp;int&nbsp;,
&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;varchar&nbsp;(60),
&nbsp;&nbsp;&nbsp;&nbsp;age&nbsp;int&nbsp;,
&nbsp;&nbsp;&nbsp;&nbsp;address&nbsp;varchar&nbsp;(30),
&nbsp;&nbsp;&nbsp;&nbsp;salary&nbsp;int
);

insert&nbsp;into&nbsp;company&nbsp;values(1,'Paul',32,'California',20000);
insert&nbsp;into&nbsp;company&nbsp;values(2,'Allen',25,&nbsp;'Texas',15000);
insert&nbsp;into&nbsp;company&nbsp;values(3,'Teddy',23,'Norway',20000);
insert&nbsp;into&nbsp;company&nbsp;values(4,'Mark',25,'Rich-Mond',65000);
insert&nbsp;into&nbsp;company&nbsp;values(5,'David',27,'Texas',85000);
insert&nbsp;into&nbsp;company&nbsp;values(6,'Kim',22,'South-Hall',45000);
insert&nbsp;into&nbsp;company&nbsp;values(7,'James',24,'Houston',10000);

--找到小于20000的薪金总和
WITH&nbsp;RECURSIVE&nbsp;t(n)&nbsp;AS&nbsp;(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VALUES&nbsp;(0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UNION&nbsp;ALL
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SELECT&nbsp;salary&nbsp;FROM&nbsp;company&nbsp;WHERE&nbsp;salary&nbsp;<&nbsp;20000
)
SELECT&nbsp;SUM(n)&nbsp;FROM&nbsp;t

--删除指定的公司行,RETURNING子句返回它们的内容;然后主查询读取输出,并将其插入到COMPANY1&nbsp;表:
&nbsp;
CREATE&nbsp;TABLE&nbsp;COMPANY1(
&nbsp;&nbsp;&nbsp;ID&nbsp;INT&nbsp;PRIMARY&nbsp;KEY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NOT&nbsp;NULL,
&nbsp;&nbsp;&nbsp;NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TEXT&nbsp;&nbsp;&nbsp;&nbsp;NOT&nbsp;NULL,
&nbsp;&nbsp;&nbsp;AGE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;INT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NOT&nbsp;NULL,
&nbsp;&nbsp;&nbsp;ADDRESS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CHAR(50),
&nbsp;&nbsp;&nbsp;SALARY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REAL
);
WITH&nbsp;moved_rows&nbsp;AS&nbsp;(
&nbsp;&nbsp;&nbsp;&nbsp;DELETE&nbsp;FROM&nbsp;COMPANY
&nbsp;&nbsp;&nbsp;&nbsp;WHERE
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SALARY&nbsp;>=&nbsp;30000
&nbsp;&nbsp;&nbsp;&nbsp;RETURNING&nbsp;*
)
INSERT&nbsp;INTO&nbsp;COMPANY1&nbsp;(SELECT&nbsp;*&nbsp;FROM&nbsp;moved_rows);
&nbsp;
SELECT&nbsp;*&nbsp;FROM&nbsp;COMPANY;
SELECT&nbsp;*&nbsp;FROM&nbsp;COMPANY1;

--&nbsp;省市区域字符串连接拼接测试
create&nbsp;table&nbsp;tb(id&nbsp;varchar(3)&nbsp;,&nbsp;pid&nbsp;varchar(3)&nbsp;,&nbsp;name&nbsp;varchar(10));&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('002'&nbsp;,&nbsp;0&nbsp;,&nbsp;'浙江省');&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('001'&nbsp;,&nbsp;0&nbsp;,&nbsp;'广东省');&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('003'&nbsp;,&nbsp;'002'&nbsp;,&nbsp;'衢州市');&nbsp;&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('004'&nbsp;,&nbsp;'002'&nbsp;,&nbsp;'杭州市')&nbsp;;&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('005'&nbsp;,&nbsp;'002'&nbsp;,&nbsp;'湖州市');&nbsp;&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('006'&nbsp;,&nbsp;'002'&nbsp;,&nbsp;'嘉兴市')&nbsp;;&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('007'&nbsp;,&nbsp;'002'&nbsp;,&nbsp;'宁波市');&nbsp;&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('008'&nbsp;,&nbsp;'002'&nbsp;,&nbsp;'绍兴市')&nbsp;;&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('009'&nbsp;,&nbsp;'002'&nbsp;,&nbsp;'台州市');&nbsp;&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('010'&nbsp;,&nbsp;'002'&nbsp;,&nbsp;'温州市')&nbsp;;&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('011'&nbsp;,&nbsp;'002'&nbsp;,&nbsp;'丽水市');&nbsp;&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('012'&nbsp;,&nbsp;'002'&nbsp;,&nbsp;'金华市')&nbsp;;&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('013'&nbsp;,&nbsp;'002'&nbsp;,&nbsp;'舟山市');&nbsp;&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('014'&nbsp;,&nbsp;'004'&nbsp;,&nbsp;'上城区')&nbsp;;&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('015'&nbsp;,&nbsp;'004'&nbsp;,&nbsp;'下城区');&nbsp;&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('016'&nbsp;,&nbsp;'004'&nbsp;,&nbsp;'拱墅区')&nbsp;;&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('017'&nbsp;,&nbsp;'004'&nbsp;,&nbsp;'余杭区')&nbsp;;&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('018'&nbsp;,&nbsp;'011'&nbsp;,&nbsp;'金东区')&nbsp;;&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('019'&nbsp;,&nbsp;'001'&nbsp;,&nbsp;'广州市')&nbsp;;&nbsp;
insert&nbsp;into&nbsp;tb&nbsp;values('020'&nbsp;,&nbsp;'001'&nbsp;,&nbsp;'深圳市')&nbsp;;

with&nbsp;RECURSIVE&nbsp;cte&nbsp;as
(
select&nbsp;a.id,cast(a.name&nbsp;as&nbsp;varchar(100))&nbsp;from&nbsp;tb&nbsp;a&nbsp;where&nbsp;id='002'
union&nbsp;all&nbsp;
select&nbsp;k.id,cast(c.name||'>'||k.name&nbsp;as&nbsp;varchar(100))&nbsp;as&nbsp;name&nbsp;&nbsp;from&nbsp;tb&nbsp;k&nbsp;inner&nbsp;join&nbsp;cte&nbsp;c&nbsp;on&nbsp;c.id&nbsp;=&nbsp;k.pid
)select&nbsp;id,name&nbsp;from&nbsp;cte&nbsp;;

--&nbsp;同表递归查询
with&nbsp;RECURSIVE&nbsp;orgIdRelations&nbsp;as
(
select&nbsp;a.i_orgid,cast(a.i_orgid&nbsp;as&nbsp;varchar(100))&nbsp;as&nbsp;parentIds&nbsp;from&nbsp;xh_ht.fs_yw_base_org&nbsp;a&nbsp;where&nbsp;a.i_orgid&nbsp;=1
&nbsp;&nbsp;&nbsp;union&nbsp;all&nbsp;
select&nbsp;k.i_orgid,&nbsp;cast(c.parentIds||','||k.i_orgid&nbsp;as&nbsp;varchar(100))&nbsp;as&nbsp;parentIds&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;from&nbsp;xh_ht.fs_yw_base_org&nbsp;k&nbsp;inner&nbsp;join&nbsp;orgIdRelations&nbsp;c&nbsp;on&nbsp;c.i_orgid&nbsp;=&nbsp;k.i_orgpid
)
select&nbsp;i_orgid,parentIds&nbsp;from&nbsp;orgIdRelations&nbsp;;

查看组织机构名称递归

--&nbsp;同表递归查询
with&nbsp;RECURSIVE&nbsp;orgNames&nbsp;as
(
select&nbsp;a.i_orgid,cast(a.c_orgname&nbsp;as&nbsp;varchar(1000))&nbsp;as&nbsp;orgName&nbsp;from&nbsp;xh_ht.fs_yw_base_org&nbsp;a&nbsp;where&nbsp;a.i_orgid=1
&nbsp;&nbsp;&nbsp;union&nbsp;all&nbsp;
select&nbsp;k.i_orgid,cast(c.orgName||'>'||k.c_orgname&nbsp;as&nbsp;varchar(1000))&nbsp;as&nbsp;orgName&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;from&nbsp;xh_ht.fs_yw_base_org&nbsp;k&nbsp;inner&nbsp;join&nbsp;orgNames&nbsp;c&nbsp;on&nbsp;c.i_orgid&nbsp;=&nbsp;k.i_orgpid
)
select&nbsp;i_orgid,orgName&nbsp;from&nbsp;orgNames&nbsp;;