数据库:SQLSERVER 2008
原始数据表(TestTable)如下,需要统计每个数字出现的个数,不希望在程序中全部取出后逐个切分相加,所以想到用SQL实现切分统计
colunname
02;03;04
01
01;02;03
02;03
02;03;04
01
02;04
01;03
01;02
02;05
01
02
03
01;02
01
01
01;03
01;02
02
实现:利用 master..spt_values系统表的自增常量切分
select
-- 截取当前b的
index的位置开始,第一个出现切分符的内容substring(a.[columname], b.number, charindex(';', a.[columname] + ';', b.number) - b.number) as ans1
FROM TestTable a,
-- 系统表
master..spt_values b
WHERE
-- 从0开始的自增正整数
b.type='p'
-- 从第一个字符截取到切分符的位置';',相当于index
and substring(';' + a.[columname],b.number, 1) = ';'
具体执行顺序大致如下假设当前字符串为'12;345;6'
1. b.number = 0 看判断条件 substring ( ';12;345;6' ,0 , 1 ) = null(知识点注解) 不等于 = ';' 执行下一步b.number+1
2. b.number = 1 看判断条件 substring ( ';12;345;6' ,1 , 1 ) = ';'因此取值
substring ( '12;345;6' , 1 , charindex ( ';' , '12;345;6' + ';' , 1 ) - 1 )而
charindex ( ';' , '12;345;6 ;' , 1 ) = 3 所以相当于取
substring('12;345;6', 1, 2) 因此取出了 12
3. b.number = 2 看判断条件 substring ( ';12;345;6' ,2 , 1 ) = 1 同1
4. b.number = 3 看判断条件 substring(';12;345;6',3, 1) = 1 同1
4. b.number = 4 看判断条件 substring(';12;345;6',4, 1) = ';'因此取值
substring ( '12;345;6' , 4 , charindex ( ';' , '12;345;6' + ';' , 4 ) - 4 )而
charindex ( ';' , '12;345;6 ;' , 4 ) = 7 所以相当于取
substring('12;345;6', 4, 3) 因此取出了 345
。。。。
执行上述SQL取出结果
03
02
03
02
03
04
01
02
04
01
03
01
02
02
05
01
02
03
01
02
01
01
01
03
01
02
02
再对此数据结果进行统计
注意点:
SQLSERVER的 [SUBSTRING](expression, start, length) 方法 其中的start位置是从1开始,而不是从0开始;
[SUBSTRING](expression, expression[ , start]) 方法 中的start位置也是从1开始,而不是从0开始
这些与C#等语言从0开始索引不同
来自为知笔记(Wiz)