A表
字段(主键) 字段2
1 abc;def
2 123;456
B表
字段(主键) 字段2
3 abcd
4 456
判断A表字段2以分号隔开的值是否在B表中存在,存在则不记录,反之记录该数据.
例子返回的A表数据
1 abc
1 def
2 123
请教这个sql怎么写啊
8 个解决方案
#1
判断A表字段2以分号隔开的值是否在B表中存在,存在则不记录,反之记录该数据.
例子返回的A表数据
1 abc
1 def
2 123
没看明白这个逻辑为什么会返回这个数据?
例子返回的A表数据
1 abc
1 def
2 123
没看明白这个逻辑为什么会返回这个数据?
#2
1 def
这个数据,是根据什么规则包含的?
这个数据,是根据什么规则包含的?
#3
select a.col1,b.col2
from a,b
where instr(a.col2,b.col2)>0;
比较简单一点的是instr,就是上例,不过有缺陷,比如b表字段是ab,而不是abc也会匹配到。
复杂点的是把a表中的字段2全行转列,然后再精确匹配b表字段2
from a,b
where instr(a.col2,b.col2)>0;
比较简单一点的是instr,就是上例,不过有缺陷,比如b表字段是ab,而不是abc也会匹配到。
复杂点的是把a表中的字段2全行转列,然后再精确匹配b表字段2
#4
其实就是把A表中字段2的已分号拆开后的值,判断在B表字段2中是否存在
#5
把A表字段2的值以分号隔开然后在判断B表是否存在,不存在的话就记录
#7
先拆分再匹配。
将a表的1 abc;def 拆成形如
1 abc
1 def
再关联b表
其实从效率上来将,用存储过程来处理可能会更合适
将a表的1 abc;def 拆成形如
1 abc
1 def
再关联b表
其实从效率上来将,用存储过程来处理可能会更合适
#8
select aaaa.id,aaaa.str from (
select distinct aaa.id, aaa.str, aaa.flag,count(*) count
from (select aa.id,
aa.str str,
b.str str1,
case
when aa.str = b.str then
1
else
0
end flag
from (select a.id, to_char(wm_concat(a.str)) str
from (select t.id,
case
when instr(t.str, ';') > 0 then
substr(t.str, 1, instr(t.str, ';') - 1)
end str, --如果有分号,则切割分号前半部分字段
case
when instr(t.str, ';') > 0 then
substr(t.str,
instr(t.str, ';') + 1,
length(t.str) - instr(t.str, ';')) --切割字段
end str1 --如果有分号,则切割分号后半部分字段
from (select 1 ID, 'abc;def' str
from dual
union all
select 2, '123;456' from dual) t) a
group by a.id --进行分号前半部分的行转列
union
select a.id, to_char(wm_concat(a.str1)) str
from (select t.id,
case
when instr(t.str, ';') > 0 then
substr(t.str, 1, instr(t.str, ';') - 1)
end str, --如果有分号,则切割分号前半部分字段
case
when instr(t.str, ';') > 0 then
substr(t.str,
instr(t.str, ';') + 1,
length(t.str) - instr(t.str, ';')) --切割字段
end str1 --如果有分号,则切割分号后半部分字段
from (select 1 ID, 'abc;def' str
from dual
union all
select 2, '123;456' from dual --测试数据
) t) a
group by a.id --进行分号后半部分的行转列
) aa
left join
(select 3 ID, 'abcd' str
from dual
union all
select 4, '456' from dual --测试数据
) b on 1 = 1 --产生笛卡尔乘积如切割后的字段与B表中相同则标记为1,不同则标记为0
) aaa
group by aaa.id, aaa.str, aaa.flag
) aaaa where aaaa.flag=0 and aaaa.count=(select count(*) from (select 3 ID, 'abcd' str
from dual
union all
select 4, '456' from dual ))
--把flga标记为0且在B表中都不存在的记录列出来
貌似写得有点复杂,仅供参考
select distinct aaa.id, aaa.str, aaa.flag,count(*) count
from (select aa.id,
aa.str str,
b.str str1,
case
when aa.str = b.str then
1
else
0
end flag
from (select a.id, to_char(wm_concat(a.str)) str
from (select t.id,
case
when instr(t.str, ';') > 0 then
substr(t.str, 1, instr(t.str, ';') - 1)
end str, --如果有分号,则切割分号前半部分字段
case
when instr(t.str, ';') > 0 then
substr(t.str,
instr(t.str, ';') + 1,
length(t.str) - instr(t.str, ';')) --切割字段
end str1 --如果有分号,则切割分号后半部分字段
from (select 1 ID, 'abc;def' str
from dual
union all
select 2, '123;456' from dual) t) a
group by a.id --进行分号前半部分的行转列
union
select a.id, to_char(wm_concat(a.str1)) str
from (select t.id,
case
when instr(t.str, ';') > 0 then
substr(t.str, 1, instr(t.str, ';') - 1)
end str, --如果有分号,则切割分号前半部分字段
case
when instr(t.str, ';') > 0 then
substr(t.str,
instr(t.str, ';') + 1,
length(t.str) - instr(t.str, ';')) --切割字段
end str1 --如果有分号,则切割分号后半部分字段
from (select 1 ID, 'abc;def' str
from dual
union all
select 2, '123;456' from dual --测试数据
) t) a
group by a.id --进行分号后半部分的行转列
) aa
left join
(select 3 ID, 'abcd' str
from dual
union all
select 4, '456' from dual --测试数据
) b on 1 = 1 --产生笛卡尔乘积如切割后的字段与B表中相同则标记为1,不同则标记为0
) aaa
group by aaa.id, aaa.str, aaa.flag
) aaaa where aaaa.flag=0 and aaaa.count=(select count(*) from (select 3 ID, 'abcd' str
from dual
union all
select 4, '456' from dual ))
--把flga标记为0且在B表中都不存在的记录列出来
貌似写得有点复杂,仅供参考
#1
判断A表字段2以分号隔开的值是否在B表中存在,存在则不记录,反之记录该数据.
例子返回的A表数据
1 abc
1 def
2 123
没看明白这个逻辑为什么会返回这个数据?
例子返回的A表数据
1 abc
1 def
2 123
没看明白这个逻辑为什么会返回这个数据?
#2
1 def
这个数据,是根据什么规则包含的?
这个数据,是根据什么规则包含的?
#3
select a.col1,b.col2
from a,b
where instr(a.col2,b.col2)>0;
比较简单一点的是instr,就是上例,不过有缺陷,比如b表字段是ab,而不是abc也会匹配到。
复杂点的是把a表中的字段2全行转列,然后再精确匹配b表字段2
from a,b
where instr(a.col2,b.col2)>0;
比较简单一点的是instr,就是上例,不过有缺陷,比如b表字段是ab,而不是abc也会匹配到。
复杂点的是把a表中的字段2全行转列,然后再精确匹配b表字段2
#4
其实就是把A表中字段2的已分号拆开后的值,判断在B表字段2中是否存在
#5
把A表字段2的值以分号隔开然后在判断B表是否存在,不存在的话就记录
#6
#7
先拆分再匹配。
将a表的1 abc;def 拆成形如
1 abc
1 def
再关联b表
其实从效率上来将,用存储过程来处理可能会更合适
将a表的1 abc;def 拆成形如
1 abc
1 def
再关联b表
其实从效率上来将,用存储过程来处理可能会更合适
#8
select aaaa.id,aaaa.str from (
select distinct aaa.id, aaa.str, aaa.flag,count(*) count
from (select aa.id,
aa.str str,
b.str str1,
case
when aa.str = b.str then
1
else
0
end flag
from (select a.id, to_char(wm_concat(a.str)) str
from (select t.id,
case
when instr(t.str, ';') > 0 then
substr(t.str, 1, instr(t.str, ';') - 1)
end str, --如果有分号,则切割分号前半部分字段
case
when instr(t.str, ';') > 0 then
substr(t.str,
instr(t.str, ';') + 1,
length(t.str) - instr(t.str, ';')) --切割字段
end str1 --如果有分号,则切割分号后半部分字段
from (select 1 ID, 'abc;def' str
from dual
union all
select 2, '123;456' from dual) t) a
group by a.id --进行分号前半部分的行转列
union
select a.id, to_char(wm_concat(a.str1)) str
from (select t.id,
case
when instr(t.str, ';') > 0 then
substr(t.str, 1, instr(t.str, ';') - 1)
end str, --如果有分号,则切割分号前半部分字段
case
when instr(t.str, ';') > 0 then
substr(t.str,
instr(t.str, ';') + 1,
length(t.str) - instr(t.str, ';')) --切割字段
end str1 --如果有分号,则切割分号后半部分字段
from (select 1 ID, 'abc;def' str
from dual
union all
select 2, '123;456' from dual --测试数据
) t) a
group by a.id --进行分号后半部分的行转列
) aa
left join
(select 3 ID, 'abcd' str
from dual
union all
select 4, '456' from dual --测试数据
) b on 1 = 1 --产生笛卡尔乘积如切割后的字段与B表中相同则标记为1,不同则标记为0
) aaa
group by aaa.id, aaa.str, aaa.flag
) aaaa where aaaa.flag=0 and aaaa.count=(select count(*) from (select 3 ID, 'abcd' str
from dual
union all
select 4, '456' from dual ))
--把flga标记为0且在B表中都不存在的记录列出来
貌似写得有点复杂,仅供参考
select distinct aaa.id, aaa.str, aaa.flag,count(*) count
from (select aa.id,
aa.str str,
b.str str1,
case
when aa.str = b.str then
1
else
0
end flag
from (select a.id, to_char(wm_concat(a.str)) str
from (select t.id,
case
when instr(t.str, ';') > 0 then
substr(t.str, 1, instr(t.str, ';') - 1)
end str, --如果有分号,则切割分号前半部分字段
case
when instr(t.str, ';') > 0 then
substr(t.str,
instr(t.str, ';') + 1,
length(t.str) - instr(t.str, ';')) --切割字段
end str1 --如果有分号,则切割分号后半部分字段
from (select 1 ID, 'abc;def' str
from dual
union all
select 2, '123;456' from dual) t) a
group by a.id --进行分号前半部分的行转列
union
select a.id, to_char(wm_concat(a.str1)) str
from (select t.id,
case
when instr(t.str, ';') > 0 then
substr(t.str, 1, instr(t.str, ';') - 1)
end str, --如果有分号,则切割分号前半部分字段
case
when instr(t.str, ';') > 0 then
substr(t.str,
instr(t.str, ';') + 1,
length(t.str) - instr(t.str, ';')) --切割字段
end str1 --如果有分号,则切割分号后半部分字段
from (select 1 ID, 'abc;def' str
from dual
union all
select 2, '123;456' from dual --测试数据
) t) a
group by a.id --进行分号后半部分的行转列
) aa
left join
(select 3 ID, 'abcd' str
from dual
union all
select 4, '456' from dual --测试数据
) b on 1 = 1 --产生笛卡尔乘积如切割后的字段与B表中相同则标记为1,不同则标记为0
) aaa
group by aaa.id, aaa.str, aaa.flag
) aaaa where aaaa.flag=0 and aaaa.count=(select count(*) from (select 3 ID, 'abcd' str
from dual
union all
select 4, '456' from dual ))
--把flga标记为0且在B表中都不存在的记录列出来
貌似写得有点复杂,仅供参考