0

我的表中有一个 XML 列,如下所示:

<word A="al"   B="h"   C="Ps" />
<word A="has"  B="es"  C="Pf" />
<word A="mom"  B="es"  C="Ph" />

我需要像这样转换成表格:

 word  | A  | B  | C
 ====================
   al  | A1 | B1 | C1
   has | A2 | B2 | C2
   mom | A3 | B2 | C3

我想通过 SQL Server 中的一个函数来做。

谢谢!

4

1 回答 1

2

在这里猜测数据类型,并猜测您不是要转换a1->A1等。

DECLARE @x TABLE(XMLFIELD XML);

INSERT @x SELECT '<word A="a1"  B="b1"  C="c1" />'
UNION ALL SELECT '<word A="a2"  B="b2"  C="c2" />'
UNION ALL SELECT '<word A="a3"  B="b2"  C="c3" />';

-- INSERT INTO dbo.OtherTable
SELECT 
  A = x.a.value('@A', 'varchar(32)'),
  B = x.a.value('@B', 'varchar(32)'),
  C = x.a.value('@C', 'varchar(32)')
FROM @x AS src
CROSS APPLY src.XMLFIELD.nodes('word') AS x(a);

结果:

A       B       C
------- ------- -------
a1      b1      c1
a2      b2      c2
a3      b2      c3

编辑

现在您已经完全改变了问题,使我的回答看起来很疯狂并且与您的问题完全无关,让我们再试一次。我再次在这里进行一些猜测,因为您没有很好地描述您的逻辑或要求。每次看到新值时,B 列都会增加吗?与C列相同吗?是否有可能存在不在连续行中的重复项?

DECLARE @x TABLE(XMLFIELD XML);

INSERT @x SELECT '<word A="al"   B="h"   C="Ps" />'
UNION ALL SELECT '<word A="has"  B="es"  C="Pf" />'
UNION ALL SELECT '<word A="mom"  B="es"  C="Ph" />';

;WITH y AS
(
  SELECT 
    word = x.a.value('@A', 'varchar(32)'),
    n = ROW_NUMBER() OVER (ORDER BY x.a.value('@A', 'varchar(32)')),
    B = x.a.value('@B', 'varchar(32)'),
    C = x.a.value('@C', 'varchar(32)')
  FROM @x AS src
  CROSS APPLY src.XMLFIELD.nodes('word') AS x(a)
)
SELECT word, 
    A = 'A' + RTRIM(n),
    B = 'B' + RTRIM((SELECT COUNT(*)+1 FROM y AS y2 WHERE n < y.n AND B <> y.B)),
    C = 'C' + RTRIM((SELECT COUNT(*)+1 FROM y AS y2 WHERE n < y.n AND C <> y.C))
FROM y 
ORDER BY word;

结果:

word   A    B    C
------ ---- ---- ----
al     A1   B1   C1
has    A2   B2   C2
mom    A3   B2   C3

如果您想要能够真正解决您的问题的连贯答案,您应该努力很好地描述您的问题(并在第一次将其正确,然后花费大量精力尝试解决错误的问题)。

于 2012-04-24T04:08:56.453 回答