如何根据sql中一列的sting值生成新行?

时间:2018-01-08 12:35:20

标签: sql sql-server tsql

我需要根据“Number”列中的值生成新行。我已经尝试过CHARINDEX和STUFF功能而没有任何成功。

Exampledata(其中“..”表示介于两者之间,“|表示和”:

CREATE TABLE mytable(
   Row         VARCHAR(3) NOT NULL PRIMARY KEY
  ,Description VARCHAR(11)
  ,Number      VARCHAR(26)
);
INSERT INTO mytable(Row,Description,Number) VALUES ('100','Testing','1105..1110|2805|2820..2830');
INSERT INTO mytable(Row,Description,Number) VALUES (NULL,NULL,NULL);
INSERT INTO mytable(Row,Description,Number) VALUES (NULL,NULL,NULL);

预期产出:

+-----+-------------+--------+
| Row | Description | Number |
+-----+-------------+--------+
| 100 | Testing     |   1105 |
| 100 | Testing     |   1106 |
| 100 | Testing     |   1107 |
| 100 | Testing     |   1108 |
| 100 | Testing     |   1109 |
| 100 | Testing     |   1110 |
| 100 | Testing     |   2805 |
| 100 | Testing     |   2820 |
| 100 | Testing     |   2821 |
| 100 | Testing     |   2822 |
| 100 | Testing     |   2823 |
| 100 | Testing     |   2824 |
| 100 | Testing     |   2825 |
| 100 | Testing     |   2826 |
| 100 | Testing     |   2827 |
| 100 | Testing     |   2828 |
| 100 | Testing     |   2829 |
| 100 | Testing     |   2830 |
+-----+-------------+--------+

3 个答案:

答案 0 :(得分:1)

使用递归CTE批量创建数字,使用大字符串的参数,只插入字符串中出现的那些

with CTE as
(
select 1105 as NN
union all
select NN + 1
from CTE
where NN < 2830
)
insert into MyTable
select 100, 'Testing', NN
from CTE
where @MyString like '%'+NN+'%'

答案 1 :(得分:1)

@vasdan,请您检查以下SQL脚本 请注意,我习惯于用户定义的功能,你可以在网上找到类似的功能 第一个是SQL split function 第二个是SQL numbers function

;with cte as (
    select 
        t.row,
        t.description,
        t.number,
        s.id grpno,
        replace(s.val,'..','|') as val
    from mytable as t
    cross apply dbo.split(t.Number,'|') s
), cte2 as (
select distinct
    row,
    description,
    grpno,
    case when ( count(*) over (partition by row, grpno) ) = 1 then null else 'X' end as range,
    min(s.val) over (partition by row, grpno) minval,
    max(s.val) over (partition by row, grpno) maxval
from cte
cross apply dbo.split(cte.val,'|') s
)
select
row,description,i
from cte2
cross apply dbo.NumbersTable(minval,maxval,1) n

这是输出

enter image description here

如果您需要帮助,我想在此示例中进一步帮助您

答案 2 :(得分:-1)

最简单的方法是为自己创建一个Numbers表。拥有数字表在许多情况下都很有用,就像这个一样。它允许您对数字范围进行非常简单的SQL查询。

查看此MSDN文章:The SQL Server Numbers Table, Explained

获得数字表后,您可以轻松地使用“WHERE numbers.number在1105和1110之间”的值填充目标表

SQL 2005引入了公用表表达式(CTE)和ROW_NUMBER()窗口函数,可以在线创建数字表。 https://technet.microsoft.com/en-us/library/ms190766(v=sql.105).aspx

表值构造函数(TVC)是在SQL 2008中引入的,它提供了一种非常紧凑的方法来创建专门针对您需要的精确行数量身定制的数字表。 https://technet.microsoft.com/en-us/library/dd776382(v=sql.110).aspx

- 进一步阅读:http://dataeducation.com/you-require-a-numbers-table/