在sql server中配对单词

时间:2015-05-21 10:50:48

标签: sql-server entity-framework

嗨我有像下面这样的数据。

表1:

id name
1  ab cd ef
2  john isner novak
3  roger federer murray
4  rafeal nadal grigor dmitrov

我需要输出如下

id pairs
1 ab cd
2 cd ef
3 john isner
4 isner novak
5 roger federer
6 federer murray
7 rafeal nadal
8 nadal grigor
9 grigor dmitrov

我尽力做到这一点,下面是我的代码。我是sql server中的函数和存储过程的新手,所以不熟悉它。请帮我解释一下代码,并简要介绍一下。

CREATE TABLE YOURTABLE AS SELECT * FROM
(
SELECT PARTDESC,
CASE WHEN WORD2 IS NOT NULL THEN  WORD1||' '||WORD2 END AS  WORD1WORD2,
CASE WHEN WORD3 IS NOT NULL THEN  WORD2||' '||WORD3 END AS  WORD2WORD3,
CASE WHEN WORD3 IS NOT NULL THEN  WORD3||' '||WORD4 END AS WORD3WORD4
FROM
(
SELECT PARTDESC, 
REVERSE(PARSENAME(REPLACE(REVERSE(NAME), ' ', '.'), 1)) AS WORD1,
REVERSE(PARSENAME(REPLACE(REVERSE(NAME), ' ', '.'), 2)) AS WORD2,
REVERSE(PARSENAME(REPLACE(REVERSE(NAME), ' ', '.'), 3)) AS WORD3,
REVERSE(PARSENAME(REPLACE(REVERSE(NAME), ' ', '.'), 4)) AS WORD4
FROM 
Table1
) A
) B
--------------------
DECLARE @colsUnpivot AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX),
@colsPivot as  NVARCHAR(MAX)

select @colsUnpivot = stuff((select ','+quotename(C.name)
     from sys.columns as C
     where C.object_id = object_id('yourtable') and
           C.name <> 'PARTDESC'
     for xml path('')), 1, 1, '')

select @colsPivot = STUFF((SELECT  ',' 
                  + quotename(PARTDESC)
                from yourtable t
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'')


set @query 
= 'select name, '+@colsPivot+'
  from
  (
    select PARTDESC, name, value
    from yourtable
    unpivot
    (
      value for name in ('+@colsUnpivot+')
    ) unpiv
  ) src
  pivot
  (
    max(value)
    for PARTDESC in ('+@colsPivot+')
  ) piv'

 exec(@query)

  ---------------

运行上面的查询后,我需要选择evry列---一次一列,然后使用union all追加..这是非常困难的任务

请帮助我完成这个......

1 个答案:

答案 0 :(得分:0)

可以使这更简单并避免动态sql:

DECLARE @t table(id int identity(1,1), name varchar(100))
INSERT @t VALUES
('ab cd ef'),
('john isner novak'),
('roger federer murray'),
('rafeal nadal grigor dmitrov')

;WITH CTE AS
(
     SELECT row_number() over(order by id) rn,id,t.c.value('.', 'VARCHAR(2000)') splitname
     FROM (
         SELECT id, x = CAST('<t>' + 
               REPLACE(name, ' ', '</t><t>') + '</t>' AS XML)
         FROM @t
     ) a
     CROSS APPLY x.nodes('/t') t(c)
)
SELECT 
  row_number() over(order by cte1.id) id, 
  cte1.splitname + ' '+ cte2.splitname name
FROM CTE cte1
JOIN CTE cte2 ON cte1.id = cte2.id and cte1.rn + 1 = cte2.rn

结果:

id  name
1   ab cd
2   cd ef
3   john isner
4   isner novak
5   roger federer
6   federer murray
7   rafeal nadal
8   nadal grigor
9   grigor dmitrov