先构造测试数据
with cte1 as
(
select 1 as aid,'1,2,3,4' as str
union all
select 2 as aid,'10,11,12,13,14'
)
,cte2 as
(
select 1 as aid,1 as bid,'1,3,4' as str union all
select 1,2 as bid,'1,2,5' union all
select 2,3 as bid,'10,15'
)
复制
根据需求 在cte2中找出 cte1.aid = cte2.aid 且 cte1.str全包含cte2.str的串,则是要找出aid = 1,bid = 1,str = ‘1,3,4’ 这行数据
第一种方法。 用 8.0特性横向派生表来解决
过程还是用公用表达式,一步一步往下写,条理会更清淅
with cte1 as
(
select 1 as aid,'1,2,3,4' as str
union all
select 2 as aid,'10,11,12,13,14'
)
,cte2 as
(
select 1 as aid,1 as bid,'1,3,4' as str union all
select 1,2 as bid,'1,2,5' union all
select 2,3 as bid,'10,15'
)
,cte3 as
(
select aid,bid,substring_index(substring_index(cte2.str,',',help_topic_id + 1),',',-1) as strid
from mysql.help_topic,cte2
where help_topic_id < LENGTH(cte2.str) - length(replace(cte2.str,',','')) + 1
)
SELECT * FROM CTE3
复制
第一步cte1与cte2是构造测试数据的语句。
第二步是cte3 将cte2的字符串拆分。
aid bid strid
1 1 1
1 1 3
1 1 4
1 2 1
1 2 2
1 2 5
2 3 10
2 3 15
with cte1 as
(
select 1 as aid,'1,2,3,4' as str
union all
select 2 as aid,'10,11,12,13,14'
)
,cte2 as
(
select 1 as aid,1 as bid,'1,3,4' as str union all
select 1,2 as bid,'1,2,5' union all
select 2,3 as bid,'10,15'
)
,cte3 as
(
select aid,bid,substring_index(substring_index(cte2.str,',',help_topic_id + 1),',',-1) as strid
from mysql.help_topic,cte2
where help_topic_id < LENGTH(cte2.str) - length(replace(cte2.str,',','')) + 1
)
,cte4 as
(
select t.* from cte1
inner join lateral
(
select aid,bid,count(*) as cnt from cte3
where POSITION(CONCAT(',',cte3.strid,',') in CONCAT(',',cte1.str,',')) >0 and cte3.aid = cte1.aid
group by aid,bid
having cnt >= (select count(*) from cte3 as t where t.aid = cte3.aid and t.bid = cte3.bid)
) as t
)
SELECT * FROM CTE4
复制
CTE4是第三步。利用横向派生表。找出全包含的记录
aid bid cnt
1 1 3
最终语句
with cte1 as
(
select 1 as aid,'1,2,3,4' as str
union all
select 2 as aid,'10,11,12,13,14'
)
,cte2 as
(
select 1 as aid,1 as bid,'1,3,4' as str union all
select 1,2 as bid,'1,2,5' union all
select 2,3 as bid,'10,15'
)
,cte3 as
(
select aid,bid,substring_index(substring_index(cte2.str,',',help_topic_id + 1),',',-1) as strid
from mysql.help_topic,cte2
where help_topic_id < LENGTH(cte2.str) - length(replace(cte2.str,',','')) + 1
)
,cte4 as
(
select t.* from cte1
inner join lateral
(
select aid,bid,count(*) as cnt from cte3
where POSITION(CONCAT(',',cte3.strid,',') in CONCAT(',',cte1.str,',')) >0 and cte3.aid = cte1.aid
group by aid,bid
having cnt >= (select count(*) from cte3 as t where t.aid = cte3.aid and t.bid = cte3.bid)
) as t
)
select cte2.* from cte2
inner join cte4 on cte4.aid = cte2.aid and cte4.bid = cte2.bid
复制
aid bid str
1 1 1,3,4
第二种方法 就不拆开讲了。
直接贴SQL
with cte1 as
(
select 1 as aid,'1,2,3,4' as str
union all
select 2 as aid,'10,11,12,13,14'
)
,cte2 as
(
select 1 as aid,1 as bid,'1,3,4' as str union all
select 1,2 as bid,'1,2,5' union all
select 2,3 as bid,'10,15'
)
,cte3 as
(
select aid,bid,substring_index(substring_index(cte2.str,',',help_topic_id + 1),',',-1) as strid
from mysql.help_topic,cte2
where help_topic_id < LENGTH(cte2.str) - length(replace(cte2.str,',','')) + 1
)
,cte4 as
(
select aid,substring_index(substring_index(cte1.str,',',help_topic_id + 1),',',-1) as strid
from mysql.help_topic,cte1
where help_topic_id < LENGTH(cte1.str) - length(replace(cte1.str,',','')) + 1
)
select * from cte2 where (aid,bid) not in
(
select aid,bid from cte3 where not exists(select 1 from cte4 where cte3.aid = cte4.aid and cte3.strid = cte4.strid)
)
复制
aid bid str
1 1 1,3,4
最后修改时间:2021-11-19 13:53:52
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。