Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL如何将一列拆分为多个变量列_Sql_Sql Server 2008_Tsql - Fatal编程技术网

SQL如何将一列拆分为多个变量列

SQL如何将一列拆分为多个变量列,sql,sql-server-2008,tsql,Sql,Sql Server 2008,Tsql,我正在使用MSSQL,试图将一个字符串列拆分为多个列。字符串列包含以分号分隔的数字,如: 190230943204;190234443204; 但是,有些行的数字比其他行多,因此在数据库中可以 190230943204;190234443204; 121340944534;340212343204;134530943204 我见过一些将一列拆分为特定数量列的解决方案,但不是可变列。数据较少的列(由逗号分隔的2系列字符串而不是3个字符串)的第三位将为空 想法?如果我必须澄清任何事情,请告诉我。

我正在使用MSSQL,试图将一个字符串列拆分为多个列。字符串列包含以分号分隔的数字,如:

190230943204;190234443204;
但是,有些行的数字比其他行多,因此在数据库中可以

190230943204;190234443204;
121340944534;340212343204;134530943204
我见过一些将一列拆分为特定数量列的解决方案,但不是可变列。数据较少的列(由逗号分隔的2系列字符串而不是3个字符串)的第三位将为空


想法?如果我必须澄清任何事情,请告诉我。

将此数据拆分为单独的列是一个非常好的开始(分离的值是一种异端邪说)。但是,“可变数量的属性”通常应建模为一个属性

entity\u properties.main\u entity\u id
是一个to
main\u entity.id

祝贺你,你在正确的道路上,这就是所谓的。你即将到达终点


然而,Beweare的这些属性应该具有相似的性质(即所有电话号码或地址等)。不要落入黑暗面(又称“黑暗面”),不要试图将所有财产都放在同一张桌子上。如果您可以识别几种类型的属性,请将每种类型存储在一个单独的表中。

如果这些都是固定长度的字符串(如问题中所述),那么您可以相当简单地完成这项工作(至少相对于其他解决方案):

选择子字符串(col,1+13*(n-1),12)作为val
从t连接
(选择1作为n联合所有选择联合所有选择3
)n

如果我是你,我会在len(t.col)上创建一个简单的函数,用“;”分隔值像这样:

IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id(N'fn_Split_List') AND xtype IN (N'FN', N'IF', N'TF'))
BEGIN
    DROP FUNCTION [dbo].[fn_Split_List]
END
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE FUNCTION [dbo].[fn_Split_List](@List NVARCHAR(512))
RETURNS @ResultRowset TABLE ( [Value] NVARCHAR(128) PRIMARY KEY)
AS
BEGIN
    DECLARE @XML xml = N'<r><![CDATA[' + REPLACE(@List, ';', ']]></r><r><![CDATA[') + ']]></r>'

    INSERT INTO @ResultRowset ([Value])
    SELECT DISTINCT RTRIM(LTRIM(Tbl.Col.value('.', 'NVARCHAR(128)')))
    FROM @xml.nodes('//r') Tbl(Col)

    RETURN
END

GO
SELECT SL.[Value]
FROM @RawData AS RD
CROSS APPLY [fn_Split_List] ([Value])  as SL
WHERE LEN(SL.[Value]) > 0
结果如下:

Value
1111111
22222222
113113131
3333333
776767676
313131312
54545353
89332131 
无论如何,函数中的逻辑并不复杂,因此您可以轻松地将其放在需要的任何位置

注意:对于用“;”分隔的值的数量没有限制,但是,如果需要,可以将函数的长度限制设置为NVARCHAR(MAX)

编辑:

正如我所看到的,您的示例中有一些行将导致函数返回空字符串。例如:

number;number;
将返回:

number
number
'' (empty string)
要清除它们,只需在上面的语句中添加以下where子句,如下所示:

IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id(N'fn_Split_List') AND xtype IN (N'FN', N'IF', N'TF'))
BEGIN
    DROP FUNCTION [dbo].[fn_Split_List]
END
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE FUNCTION [dbo].[fn_Split_List](@List NVARCHAR(512))
RETURNS @ResultRowset TABLE ( [Value] NVARCHAR(128) PRIMARY KEY)
AS
BEGIN
    DECLARE @XML xml = N'<r><![CDATA[' + REPLACE(@List, ';', ']]></r><r><![CDATA[') + ']]></r>'

    INSERT INTO @ResultRowset ([Value])
    SELECT DISTINCT RTRIM(LTRIM(Tbl.Col.value('.', 'NVARCHAR(128)')))
    FROM @xml.nodes('//r') Tbl(Col)

    RETURN
END

GO
SELECT SL.[Value]
FROM @RawData AS RD
CROSS APPLY [fn_Split_List] ([Value])  as SL
WHERE LEN(SL.[Value]) > 0

这是糟糕的数据设计。切勿在列中存储逗号分隔的数据。希望这里的目的是修复模式。你可以在这里找到你需要的:很抱歉,它们不是逗号,而是分号,用于分隔数据。可能的重复我看到了这个问题,它不是重复的,因为那里的人知道他将拆分成多少列(4)而我没有。它们确实是固定长度的字符串。你能澄清什么是“n”和“t.col”吗?什么是“val”?@user2522217
t
是表的名称
col
是包含字符串的列的名称
n
n.n
是子查询及其列的名称。
SELECT SL.[Value]
FROM @RawData AS RD
CROSS APPLY [fn_Split_List] ([Value])  as SL
WHERE LEN(SL.[Value]) > 0