在论坛中出现的比较难的sql问题:38(字符拆分 字符串检索问题)

原文: 在论坛中出现的比较难的sql问题:38(字符拆分 字符串检索问题)

最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了。

所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路。


字符串检索问题:http://bbs.csdn.net/topics/390608926

这是 http://bbs.csdn.net/topics/390530288  问题的 一个变种

ID    IndexArr
1     1,2,3,4,5
2     55,6,99,87,1000
3     7,567567,567,43,123

IndexArr 是","分割的数字
现在有字符串 '2,34,45,345,867,4,984'  
现在要检索的是  IndexArr 中每一个数字都在 字符串中出现过的  结果集。


我的解法:


    
    
  1. --1.函数
  2. if exists( select * from sys.objects where name = 'f_splitSTR' and type = 'tf')
  3. drop function dbo.f_splitSTR
  4. go
  5. create function dbo.f_splitSTR
  6. (
  7. @s varchar( 8000), --要分拆的字符串
  8. @ split varchar( 10) --分隔字符
  9. )
  10. returns @re table( --要返回的临时表
  11. col varchar( 1000) --临时表中的列
  12. )
  13. as
  14. begin
  15. declare @ len int
  16. set @ len = LEN(@ split) --分隔符不一定就是一个字符,可能是2个字符
  17. while CHARINDEX(@ split,@s) > 0
  18. begin
  19. insert into @re
  20. values( left(@s, charindex(@ split,@s) - 1))
  21. set @s = STUFF(@s, 1, charindex(@ split,@s) - 1 + @ len , '') --覆盖:字符串以及分隔符
  22. end
  23. insert into @re values(@s)
  24. return --返回临时表
  25. end
  26. go
  27. --> 测试数据:[tb]
  28. if object_id( '[tb]') is not null
  29. drop table [tb]
  30. go
  31. create table [tb]([ ID] int,[IndexArr] varchar( 19))
  32. insert [tb]
  33. select 1, '1,2,3,4,5' union all
  34. select 2, '55,6,99,87,1000' union all
  35. select 3, '7,567567,567,43,123' union ALL
  36. SELECT 4, '2,34,45'
  37. --------------开始查询--------------------------
  38. DECLARE @s VARCHAR( 1000)
  39. SET @s= '2,34,45,345,867,4,984'
  40. ;with t
  41. as
  42. (
  43. select t.ID,
  44. t.IndexArr,
  45. f.col,
  46. --把IndexArr按照分隔符,拆分成了多少个字符串
  47. COUNT(*) over( PARTITION by IndexArr) as split_str_count
  48. from tb t
  49. cross apply dbo.f_splitSTR(t.IndexArr, ',') f
  50. )
  51. select t.ID,
  52. t.IndexArr
  53. from t
  54. where charindex( col, ','+@s+ ',') > 0
  55. group by t.ID,
  56. t.IndexArr,
  57. t.split_str_count
  58. having COUNT(*) = t.split_str_count --比如2,34,45分拆为3个字符串,
  59. --那么在经过where条件过滤后,记录数也必须是3
  60. --这样说明了indexarr中的字符串都在@s变量中出现了



发布了416 篇原创文章 · 获赞 135 · 访问量 95万+

猜你喜欢

转载自www.cnblogs.com/lonelyxmas/p/12020071.html
今日推荐