SQL经典应用(一)

 
  1. SQL code问题描述:
  2. 无论是在sql 2000,还是在 sql 2005 中,都没有提供字符串的聚合函数,
  3.   所以,当我们在处理下列要求时,会比较麻烦:
  4. 有表tb, 如下:
  5. id    value
  6. ----- ------
  7. 1     aa
  8. 1     bb
  9. 2     aaa
  10. 2     bbb
  11. 2     ccc
  12. 需要得到结果:
  13. id     values
  14. ------ -----------
  15. 1      aa,bb
  16. 2      aaa,bbb,ccc
  17. 即, group by id, 求 value 的和(字符串相加)
  18. 1. 旧的解决方法
  19. -- 1. 创建处理函数
  20. CREATE FUNCTION dbo.f_str(@id int)
  21. RETURNS varchar(8000)
  22. AS
  23. BEGIN
  24.     DECLARE @r varchar(8000)
  25.     SET @r = ''
  26.     SELECT @r = @r + ',' + value
  27.     FROM tb
  28.     WHERE id=@id
  29.     RETURN STUFF(@r, 1, 1, '')
  30. END
  31. GO
  32. -- 调用函数
  33. SELECt id, values=dbo.f_str(id) 
  34. FROM tb 
  35. GROUP BY id
  36. -- 2. 新的解决方法 
  37. -- 示例数据
  38. DECLARE @t TABLE(id int, value varchar(10))
  39. INSERT @t SELECT 1, 'aa'
  40. UNION ALL SELECT 1, 'bb'
  41. UNION ALL SELECT 2, 'aaa'
  42. UNION ALL SELECT 2, 'bbb'
  43. UNION ALL SELECT 2, 'ccc'
  44. -- 查询处理
  45. SELECT *
  46. FROM(
  47.     SELECT DISTINCT 
  48.         id
  49.     FROM @t
  50. )A
  51. OUTER APPLY(
  52.     SELECT 
  53.         [values]= STUFF(REPLACE(REPLACE(
  54.             (
  55.                 SELECT value FROM @t N
  56.                 WHERE id = A.id
  57.                 FOR XML AUTO
  58.             ), '<N value="'','), '"/>'''), 1, 1, '')
  59. )N
  60. /*--结果
  61. id          values
  62. ----------- ----------------
  63. 1           aa,bb
  64. 2           aaa,bbb,ccc
  65. (2 行受影响)
  66. --*/
  67. --各种字符串分函数
  68. --3.3.1 使用游标法进行字符串合并处理的示例。
  69. --处理的数据
  70. CREATE TABLE tb(col1 varchar(10),col2 int)
  71. INSERT tb SELECT 'a',1
  72. UNION ALL SELECT 'a',2
  73. UNION ALL SELECT 'b',1
  74. UNION ALL SELECT 'b',2
  75. UNION ALL SELECT 'b',3
  76. --合并处理
  77. --定义结果集表变量
  78. DECLARE @t TABLE(col1 varchar(10),col2 varchar(100))
  79. --定义游标并进行合并处理
  80. DECLARE tb CURSOR LOCAL
  81. FOR
  82. SELECT col1,col2 FROM tb ORDER BY  col1,col2
  83. DECLARE @col1_old varchar(10),@col1 varchar(10),@col2 int,@s varchar(100)
  84. OPEN tb
  85. FETCH tb INTO @col1,@col2
  86. SELECT @col1_old=@col1,@s=''
  87. WHILE @@FETCH_STATUS=0
  88. BEGIN
  89.     IF @col1=@col1_old
  90.         SELECT @s=@s+','+CAST(@col2 as varchar)
  91.     ELSE
  92.     BEGIN
  93.         INSERT @t VALUES(@col1_old,STUFF(@s,1,1,''))
  94.         SELECT @s=','+CAST(@col2 as varchar),@col1_old=@col1
  95.     END
  96.     FETCH tb INTO @col1,@col2
  97. END
  98. INSERT @t VALUES(@col1_old,STUFF(@s,1,1,''))
  99. CLOSE tb
  100. DEALLOCATE tb
  101. --显示结果并删除测试数据
  102. SELECT * FROM @t
  103. DROP TABLE tb
  104. /*--结果
  105. col1       col2
  106. ---------- -----------
  107. a          1,2
  108. b          1,2,3
  109. --*/
  110. GO
  111. /*==============================================*/
  112. --3.3.2 使用用户定义函数,配合SELECT处理完成字符串合并处理的示例
  113. --处理的数据
  114. CREATE TABLE tb(col1 varchar(10),col2 int)
  115. INSERT tb SELECT 'a',1
  116. UNION ALL SELECT 'a',2
  117. UNION ALL SELECT 'b',1
  118. UNION ALL SELECT 'b',2
  119. UNION ALL SELECT 'b',3
  120. GO
  121. --合并处理函数
  122. CREATE FUNCTION dbo.f_str(@col1 varchar(10))
  123. RETURNS varchar(100)
  124. AS
  125. BEGIN
  126.     DECLARE @re varchar(100)
  127.     SET @re=''
  128.     SELECT @re=@re+','+CAST(col2 as varchar)
  129.     FROM tb
  130.     WHERE col1=@col1
  131.     RETURN(STUFF(@re,1,1,''))
  132. END
  133. GO
  134. --调用函数
  135. SELECT col1,col2=dbo.f_str(col1) FROM tb GROUP BY col1
  136. --删除测试
  137. DROP TABLE tb
  138. DROP FUNCTION f_str
  139. /*--结果
  140. col1       col2
  141. ---------- -----------
  142. a          1,2
  143. b          1,2,3
  144. --*/
  145. GO
  146. /*==============================================*/
  147. --3.3.3 使用临时表实现字符串合并处理的示例
  148. --处理的数据
  149. CREATE TABLE tb(col1 varchar(10),col2 int)
  150. INSERT tb SELECT 'a',1
  151. UNION ALL SELECT 'a',2
  152. UNION ALL SELECT 'b',1
  153. UNION ALL SELECT 'b',2
  154. UNION ALL SELECT 'b',3
  155. --合并处理
  156. SELECT col1,col2=CAST(col2 as varchar(100)) 
  157. INTO #t FROM tb
  158. ORDER BY col1,col2
  159. DECLARE @col1 varchar(10),@col2 varchar(100)
  160. UPDATE #t SET 
  161.     @col2=CASE WHEN @col1=col1 THEN @col2+','+col2 ELSE col2 END,
  162.     @col1=col1,
  163.     col2=@col2
  164. SELECT * FROM #t
  165. /*--更新处理后的临时表
  166. col1       col2
  167. ---------- -------------
  168. a          1
  169. a          1,2
  170. b          1
  171. b          1,2
  172. b          1,2,3
  173. --*/
  174. --得到最终结果
  175. SELECT col1,col2=MAX(col2) FROM #t GROUP BY col1
  176. /*--结果
  177. col1       col2
  178. ---------- -----------
  179. a          1,2
  180. b          1,2,3
  181. --*/
  182. --删除测试
  183. DROP TABLE tb,#t
  184. GO
  185. /*==============================================*/
  186. --3.3.4.1 每组 <=2 条记录的合并
  187. --处理的数据
  188. CREATE TABLE tb(col1 varchar(10),col2 int)
  189. INSERT tb SELECT 'a',1
  190. UNION ALL SELECT 'a',2
  191. UNION ALL SELECT 'b',1
  192. UNION ALL SELECT 'b',2
  193. UNION ALL SELECT 'c',3
  194. --合并处理
  195. SELECT col1,
  196.     col2=CAST(MIN(col2) as varchar)
  197.         +CASE 
  198.             WHEN COUNT(*)=1 THEN ''
  199.             ELSE ','+CAST(MAX(col2) as varchar)
  200.         END
  201. FROM tb
  202. GROUP BY col1
  203. DROP TABLE tb
  204. /*--结果
  205. col1       col2      
  206. ---------- ----------
  207. a          1,2
  208. b          1,2
  209. c          3
  210. --*/
  211. --3.3.4.2 每组 <=3 条记录的合并
  212. --处理的数据
  213. CREATE TABLE tb(col1 varchar(10),col2 int)
  214. INSERT tb SELECT 'a',1
  215. UNION ALL SELECT 'a',2
  216. UNION ALL SELECT 'b',1
  217. UNION ALL SELECT 'b',2
  218. UNION ALL SELECT 'b',3
  219. UNION ALL SELECT 'c',3
  220. --合并处理
  221. SELECT col1,
  222.     col2=CAST(MIN(col2) as varchar)
  223.         +CASE 
  224.             WHEN COUNT(*)=3 THEN ','
  225.                 +CAST((SELECT col2 FROM tb WHERE col1=a.col1 AND col2 NOT IN(MAX
  226. (a.col2),MIN(a.col2))) as varchar)
  227.             ELSE ''
  228.         END
  229.         +CASE 
  230.             WHEN COUNT(*)>=2 THEN ','+CAST(MAX(col2) as varchar)
  231.             ELSE ''
  232.         END
  233. FROM tb a
  234. GROUP BY col1
  235. DROP TABLE tb
  236. /*--结果
  237. col1       col2
  238. ---------- ------------
  239. a          1,2
  240. b          1,2,3
  241. c          3
  242. --*/
  243. GO
  244. if not object_id('A') is null
  245.     drop table A
  246. Go
  247. Create table A([id] int,[cname] nvarchar(2))
  248. Insert A
  249. select 1,N'张三' union all
  250. select 2,N'李四' union all
  251. select 3,N'王五' union all
  252. select 4,N'蔡六'
  253. Go
  254. --> --> 
  255. if not object_id('B') is null
  256.     drop table B
  257. Go
  258. Create table B([id] int,[cname] nvarchar(5))
  259. Insert B
  260. select 1,N'1,2,3' union all
  261. select 2,N'3,4'
  262. Go
  263. create function F_str(@cname nvarchar(100))
  264. returns nvarchar(100)
  265. as
  266. begin 
  267. select @cname=replace(@cname,ID,[cname]) from A where patindex('%,'+rtrim(ID)
  268. +',%',','+@cname+',')>0
  269. return @cname
  270. end
  271. go
  272. select [id],dbo.F_str([cname])[cname] from B
  273. id          cname
  274. ----------- -------------------------------------------------------------------------------
  275. ---------------------
  276. 1           张三,李四,王五
  277. 2           王五,蔡六
  278. (2 個資料列受到影響)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值