2012-03-15 135 views
1

我想使用SQL(不usnig TSQL /循环等)在表如何将单元格中的CSV值转换为Rows和UnPivot?

Name DependsOn-CSV 
---- ------------- 
a  b,c 
b  d 
c 
d 
e  g 
f  b,e,a,g 
g 
h  a 

数据转换为

Name DependsOn-Rows 
---- -------------- 
a  b 
a  C 
b  d 
c 
d 
e  g 
f  b 
f  e 
f  a 
f  g 
g 
h  a 

然后

C1 C2 C3 C4 C5 
-- -- -- -- -- 
f 
    b 
     d 
    e 
     g 
    a 
     b 
      d 
     c 
    g 
h 
    a 
     b 
      d 
     c 

。这可以做到吗?


更新:我从关系角度思考。因此,请不要在问题的第一部分使用XML,OpenQuery等。这里有一个与关系设计相关的问题,这就是挑战!

+5

得到最后一张表的逻辑是什么? – 2012-03-15 06:58:48

+2

@Igor:很可能它是一棵显示依赖关系的树。列位置对应于它包含的节点的层级。每隔一行包含一个与当前的项目有关的项目,以三种方式之一:一个孩子,一个兄弟姐妹,一个父母的兄弟姐妹。但是,OP应该澄清这一点。 – 2012-03-15 08:53:32

+0

是........... :) – Faiz 2012-03-25 06:18:33

回答

1

你可以通过这样得到的第一个结果:

测试数据

DECLARE @tbl TABLE(Name VARCHAR(100),DependsOnCSV VARCHAR(100)) 

INSERT INTO @tbl 
VALUES 
    ('a','b,c'), 
    ('b','d'), 
    ('c',''), 
    ('d',''), 
    ('e','g'), 
    ('f','b,e,a,g'), 
    ('g',''), 
    ('h','a') 

拆分功能

CREATE FUNCTION Split 
(
    @delimited nvarchar(max), 
    @delimiter nvarchar(100) 
) RETURNS @t TABLE 
(
    id int identity(1,1), 
    val nvarchar(max) 
) 
AS 
BEGIN 
    declare @xml xml 
    set @xml = N'<root><r>' + replace(@delimited,@delimiter,'</r><r>') + '</r></root>' 

    insert into @t(val) 
    select 
    r.value('.','varchar(5)') as item 
    from @xml.nodes('//root/r') as records(r) 

    RETURN 
END 
GO 

替代分流的功能

CREATE FUNCTION dbo.Split (@s varchar(512),@sep char(1)) 
RETURNS table 
AS 
RETURN (
    WITH Pieces(pn, start, stop) AS (
     SELECT 1, 1, CHARINDEX(@sep, @s) 
     UNION ALL 
     SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1) 
     FROM Pieces 
     WHERE stop > 0 
    ) 
    SELECT pn, 
     SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s 
    FROM Pieces 
) 
GO 

查询

SELECT 
    tbl.Name, 
    split.val AS [DependsOn-Rows] 
FROM @tbl AS tbl 
CROSS APPLY dbo.Split(tbl.DependsOnCSV,',') split 

然后,我真的不知道如何获得第二个结果。你必须解释更多

+0

好东西:) 虽然我不喜欢xml操作,因为我正在寻找一个纯关系的答案。我个人认为xml操作和OpenQuery()调用一样好。真诚感谢你的努力,做好工作。 – Faiz 2012-03-25 07:14:44

+0

道歉,第二次看,我认为你已经解决了这个问题,使用关系方法(CROSS APPLY)。该功能可以在不使用xml的情况下重写。谢谢.. 让我们关注第二部分吧.. – Faiz 2012-03-25 07:31:42

相关问题