查询将字符串拆分为行

时间:2015-06-13 12:01:52

标签: sql tsql split rows delimiter

我有一个看起来像这样的表:

ID    Value
1     1,10
2     7,9

我希望我的结果看起来像这样:

ID   Value
1    1
1    2
1    3
1    4
1    5
1    6
1    7
1    8
1    9
1    10
2    7
2    8
2    9

我在2个数字与,之间的范围作为分隔符(值中只能有一个分隔符)以及如何将其拆分为行。

3 个答案:

答案 0 :(得分:5)

拆分以逗号分隔的数字是此问题的一小部分。解析应该在应用程序中完成,范围存储在单独的列中。出于多个原因:将数字存储为字符串是个坏主意。在一列中存储两个属性是个坏主意。实际上,将未经过处理的用户输入存储在数据库中通常也是一个坏主意。

在任何情况下,生成数字列表的一种方法是使用递归CTE:

with t as (
      select t.*, cast(left(value, charindex(',', value) - 1) as int) as first,
             cast(substring(value, charindex(',', value) + 1, 100) as int) as last
      from table t
     ),
     cte as (
      select t.id, t.first as value, t.last
      from t
      union all
      select cte.id, cte.value + 1, cte.last
      from cte
      where cte.value < cte.last
     )
select id, value
from cte
order by id, value;

如果范围非常大,您可能需要调整MAXRECURSION的值。

答案 1 :(得分:0)

任何具有多个值的字段的表格在设计方面都存在问题。处理这些记录的唯一方法是将分隔符上的值拆分并将它们放入临时表中,实现自定义拆分代码,按照说明集成CTE,或重新设计原始表以放置逗号分隔的字段进入单独的领域,例如

ID LOWLIMIT HILIMIT
1  1        10

答案 2 :(得分:0)

--create temp table for data sample DECLARE @Yourdata AS TABLE ( id INT, VALUE VARCHAR(20) ) INSERT @Yourdata ( id, VALUE ) VALUES ( 1, '1,10' ), ( 2, '7,9' ) --final query ;WITH Tally AS ( SELECT MIN(CONVERT(INT, SUBSTRING(y.VALUE, 1, CHARINDEX(',', y.value) - 1))) AS MinV , MAX(CONVERT(INT, SUBSTRING(y.VALUE, CHARINDEX(',', y.value) + 1, 18))) AS MaxV FROM @yourdata AS y UNION ALL SELECT MinV = MinV + 1 , MaxV FROM Tally WHERE MinV < Maxv ) SELECT y.id , t.minV AS value FROM @yourdata AS y JOIN tally AS t ON t.MinV BETWEEN CONVERT(INT, SUBSTRING(y.VALUE, 1, CHARINDEX(',', y.value) - 1)) AND CONVERT(INT, SUBSTRING(y.VALUE, CHARINDEX(',', y.value) + 1, 18)) ORDER BY id, minV OPTION ( MAXRECURSION 999 ) --change it if required 变体类似,但有一些差异

find: `dependencies/cmake-3.3.0-rc2/Tests/FindPackageTest/Baz': No such file or directory
find: `1.1': No such file or directory
find: `dependencies/cmake-3.3.0-rc2/Tests/FindPackageTest/Baz': No such file or directory
find: `1.2': No such file or directory
find: `dependencies/cmake-3.3.0-rc2/Tests/FindPackageTest/Baz': No such file or directory
find: `1.2/CMake': No such file or directory
find: `dependencies/cmake-3.3.0-rc2/Tests/SubDirSpaces/Another': No such file or directory
find: `Subdir': No such file or directory
find: `Sources': No such file or directory
bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `find dependencies/cmake-3.3.0-rc2/Tests/SubDirSpaces/Some(x86) Sources -maxdepth 1 \( -name '*.cpp' -o -name '*.proto' \) | grep -q .'
find: `dependencies/cmake-3.3.0-rc2/Tests/SubDirSpaces/Some': No such file or directory
find: `Examples': No such file or directory
find: `dependencies/cmake-3.3.0-rc2/Tests/SubDirSpaces/Some': No such file or directory
find: `Examples/example2': No such file or directory
find: `dependencies/cmake-3.3.0-rc2/Tests/SubDirSpaces/Some': No such file or directory
find: `Examples/example1': No such file or directory
LD -o .build_release/lib/libcaffe.so
/usr/bin/ld: /usr/local/lib/libgflags.a(gflags.cc.o): relocation R_X86_64_32S against `.rodata' can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/libgflags.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [.build_release/lib/libcaffe.so] Error 1

输出

enter image description here