根据列值

时间:2018-04-02 01:49:23

标签: sql-server duplicates

我有一张如下表所示的表格。 “Repeater”列包含字符串和整数值,基于此我希望能够复制和重复行。如果“Repeater”值是字符串(始终以逗号分隔),则行应根据有多少值进行复制,并且每行应具有其中一个值。如果“Repeater”值是一个整数,那么它应该根据该值复制该行。

+---------+--------+-----------------+
| OrderNo | Amount |    RepeaterRes  |
+---------+--------+-----------------+
| AB-001  |    100 | Orange, Apple,  |
| AB-002  |    102 | 3               |
| AB-003  |    980 | Apple           |
| AB-004  |    309 | Banana, Grapes, |
| AB-005  |    840 | 2               |
| AB-006  |    290 | 0               |
| AB-007  |    483 | 0               |
+---------+--------+-----------------+

所需输出:

+---------+--------+----------+
| OrderNo | Amount | Repeater |
+---------+--------+----------+
| AB-001  |    100 | Orange,  |
| AB-001  |    100 | Apple,   |
| AB-002  |    102 | 3        |
| AB-002  |    102 | 3        |
| AB-002  |    102 | 3        |
| AB-003  |    980 | Apple    |
| AB-004  |    309 | Banana,  |
| AB-004  |    309 | Grapes,  |
| AB-005  |    840 | 2        |
| AB-005  |    840 | 2        |
| AB-006  |    290 | 0        |
| AB-007  |    483 | 0        |
+---------+--------+----------+

1 个答案:

答案 0 :(得分:1)

假设不是2016 +

示例

Select OrderNo
      ,Amount
      ,C.*
 from  YourTable A
 Cross Apply ( values (case when try_convert(int,[RepeaterRes]) is null then [RepeaterRes] else replicate([RepeaterRes]+',',IsNull(NullIf(try_convert(int,[RepeaterRes]),0),1)) end )) B(NewString)
 Cross Apply (
                Select Repeater  = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
                 From  (Select x = Cast('<x>' + replace((Select replace(NewString,',','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
                 Cross Apply x.nodes('x') AS B(i)
             ) C
 Where C.Repeater is not null

<强>返回

OrderNo Amount  Repeater
AB-001  100     Orange
AB-001  100     Apple
AB-002  102     3
AB-002  102     3
AB-002  102     3
AB-003  980     Apple
AB-004  309     Banana
AB-004  309     Grapes
AB-005  840     2
AB-005  840     2
AB-006  290     0
AB-007  483     0