日期:2014-05-17  浏览次数:20550 次

数据拆分
刚看到一个数据拆分的例子,方法比较老,不过感觉很巧妙,不过没明白期原理,能否详细解释一下下
SQL code

--测试环境
create table tb(id int,value varchar(30))
insert into tb values(1,'aa,bb')
insert into tb values(2,'aaa,bbb,ccc')
go

SELECT TOP 8000 id = IDENTITY(int, 1, 1) INTO # FROM syscolumns a, syscolumns b 

SELECT A.id, value = SUBSTRING(A.[value], B.id, CHARINDEX(',', A.[value] + ',', B.id) - B.id)
FROM tb A, # B
WHERE SUBSTRING(',' + A.[value], B.id, 1) = ','
--最后一个查询不是很理解



------解决方案--------------------
CHARINDEX使用这个,找出存在两个逗号的字符的第一个逗号的起始位置,#表只是作为一个辅助列,产生需要用的,新版本可以使用row_number()
------解决方案--------------------
select * from tb a,# b (16000条)
#表是用来生成8000个ID号,与 tb表关联产生16000条记录;
select * from tb a,# b where SUBSTRING(',' + A.[value], B.id, 1) = ','
加个where 条件,是用来把A.[value]遍历8000个id ,取得含有','在 字符串(',' + A.[value])所在位置的B.ID值;
至于 value = SUBSTRING(A.[value], B.id, CHARINDEX(',', A.[value] + ',', B.id) - B.id)
就是将数据拆分了。
------解决方案--------------------
最后一个查询
SQL code
SELECT A.id, value = SUBSTRING(A.[value], B.id, CHARINDEX(',', A.[value] + ',', B.id) - B.id)
FROM tb A, # B
WHERE SUBSTRING(',' + A.[value], B.id, 1) = ',' 
--where后面条件比较巧妙,取得A表中value存在','所有B.id值,以此明确
--value = SUBSTRING(A.[value], B.id, CHARINDEX(',', A.[value] + ',', B.id) - B.id)这---一句截取字符串时起始和结束位置

------解决方案--------------------
这是利用数字辅助表对数据进行拆分,建议你:看不懂的时候将代码里面的各个表达式分别select出来
化简这个句子 例如
SQL code
SELECT  A.id,CHARINDEX(',', A.[value] + ',', B.id)
FROM tb A, # B
WHERE SUBSTRING(',' + A.[value], B.id, 1) = ','
/*
id          
----------- -----------
1           3
1           6
2           4
2           8
2           12
--可以看到3、6分别是第一个值的“,”位置和末尾位置(因为他在字符串末尾也加了一个“,”号)
4,8,12分别是第二个值的“,”位置
(5 行受影响)


*/

------解决方案--------------------
用临时表连接的方法,找到逗号在哪个位置上,然后拆分.
------解决方案--------------------
就是找到位置,然后截取。。。。。