将SQL列中的分隔值拆分为多行

13 浏览
0 Comments

将SQL列中的分隔值拆分为多行

我真的想在这里寻求一些建议,为了提供一些背景信息,我正在使用将来自Exchange 2007的消息跟踪日志插入到SQL中。由于每天有数百万行数据,我使用了一个批量插入语句将数据插入到SQL表中。

实际上,我实际上是将数据批量插入到一个临时表中,然后从临时表中将数据合并到实时表中,这是为了测试解析问题,因为某些字段的值周围可能有引号等。

这个方法很有效,只是收件人地址列是由一个分隔符字段分隔的,以分号字符分隔,有时可能非常长,因为可能有很多电子邮件收件人。

我想将这一列的值拆分成多行,然后插入到另一个表中。问题是,我试过的任何方法要么太慢,要么不按我想要的方式工作。

以这个示例数据为例:

message-id                                              recipient-address
2D5E558D4B5A3D4F962DA5051EE364BE06CF37A3A5@Server.com   user1@domain1.com
E52F650C53A275488552FFD49F98E9A6BEA1262E@Server.com     user2@domain2.com
4fd70c47.4d600e0a.0a7b.ffff87e1@Server.com              user3@domain3.com;user4@domain4.com;user5@domain5.com

我希望在我的收件人表中格式化如下:

message-id                                              recipient-address
2D5E558D4B5A3D4F962DA5051EE364BE06CF37A3A5@Server.com   user1@domain1.com
E52F650C53A275488552FFD49F98E9A6BEA1262E@Server.com     user2@domain2.com
4fd70c47.4d600e0a.0a7b.ffff87e1@Server.com              user3@domain3.com
4fd70c47.4d600e0a.0a7b.ffff87e1@Server.com              user4@domain4.com
4fd70c47.4d600e0a.0a7b.ffff87e1@Server.com              user5@domain5.com

有人对我如何实现这个有什么想法吗?

我很了解PowerShell,所以我尝试了它,但是即使在28K记录上使用foreach循环也需要很长时间来处理,我需要一个尽可能快/高效运行的方法。

谢谢!

0
0 Comments

在这篇文章中,我们将探讨如何将SQL列中的分隔值拆分为多行,并提供相应的解决方法。

问题:

问题是在SQL Server中,如何将包含分隔值的列拆分为多行,以便每行只包含一个值。

解决方法:

1. 如果使用的是SQL Server 2016+版本,可以使用新的STRING_SPLIT函数。这个函数可以将包含分隔符的字符串拆分为多个值,并将其作为单独的行返回。

例如:

SELECT s.[message-id], f.value
FROM dbo.SourceData AS s
CROSS APPLY STRING_SPLIT(s.[recipient-address], ';') as f;

2. 如果使用的是SQL Server 2016之前的版本,则可以创建一个拆分函数,以实现相同的效果。

例如:

CREATE FUNCTION dbo.SplitStrings
(
       NVARCHAR(MAX),
  NVARCHAR(255)
)
RETURNS TABLE
AS
  RETURN (SELECT Number = ROW_NUMBER() OVER (ORDER BY Number),
    Item FROM (SELECT Number, Item = LTRIM(RTRIM(SUBSTRING(, Number, 
    CHARINDEX(,  + , Number) - Number)))
FROM (SELECT ROW_NUMBER() OVER (ORDER BY s1.[object_id])
    FROM sys.all_objects AS s1 CROSS APPLY sys.all_objects) AS n(Number)
WHERE Number <= CONVERT(INT, LEN())
    AND SUBSTRING( + , Number, 1) = 
) AS y);
GO

然后,可以通过以下方式使用拆分函数:

SELECT s.[message-id], f.Item
FROM dbo.SourceData AS s
CROSS APPLY dbo.SplitStrings(s.[recipient-address], ';') as f;

3. 除了上述方法外,还有其他一些方法可以实现拆分字符串的效果。可以参考一些相关文章进行学习和了解。

通过使用STRING_SPLIT函数或自定义的拆分函数,我们可以将包含分隔值的SQL列拆分为多行,以便每行只包含一个值。这样可以更方便地处理和分析数据。

0
0 Comments

问题出现的原因是在SQL Server 2016之前,无法直接将一个包含分隔符的列拆分成多行。然而,SQL Server 2016引入了一个新的表函数string_split(),可以解决这个问题。

解决方法是将兼容级别设置为130(SQL Server 2016),然后使用string_split()函数来拆分列的值。这个函数将返回一个结果集,其中每个值都是从原始列的值中根据指定的分隔符拆分得到的。

以下是使用string_split()函数解决这个问题的示例代码:

-- 设置兼容级别为130
ALTER DATABASE [数据库名] SET COMPATIBILITY_LEVEL = 130;
-- 使用string_split()函数拆分列的值
SELECT value
FROM 表名
CROSS APPLY string_split(列名, '分隔符');

上述代码将返回一个包含拆分后的值的结果集,每个值都占据一行。

通过将兼容级别设置为130并使用string_split()函数,我们可以轻松地将一个包含分隔符的列拆分成多行。这为我们处理这类数据提供了更加便捷和灵活的方法。

0
0 Comments

在SQL列中拆分分隔值为多行的问题是一个常见的需求。这通常发生在某些情况下,例如当一个列中包含多个值,这些值之间使用分隔符进行分隔时。例如,我们有一个名为"MessageRecipients"的表,其中包含两列,分别是"MessageId"和"Recipients"。"Recipients"列中的值是以分号分隔的收件人邮箱地址。

出现这个问题的原因是我们需要将"Recipients"列中的每个收件人地址拆分为独立的行,以便我们可以更方便地处理和查询这些数据。

要解决这个问题,我们可以使用SQL Server 2005及以上版本中提供的CROSS APPLY和SQL Server 2016及以上版本中提供的STRING_SPLIT函数。

下面是解决方案的示例代码:

DECLARE @delimiter nvarchar(255) = ';';
-- 创建表
CREATE TABLE MessageRecipients (MessageId int, Recipients nvarchar(max));
CREATE TABLE MessageRecipient (MessageId int, Recipient nvarchar(max));
-- 插入数据
INSERT INTO MessageRecipients VALUES (1, 'user1.com; user2.com; user3.com');
INSERT INTO MessageRecipients VALUES (2, 'user.com; user.com');
-- 将数据插入MessageRecipient表中
INSERT INTO MessageRecipient
SELECT MessageId, ltrim(rtrim(value))
FROM MessageRecipients 
CROSS APPLY STRING_SPLIT(Recipients, @delimiter);
-- 输出结果
SELECT * FROM MessageRecipients;
SELECT * FROM MessageRecipient;
-- 删除表
DROP TABLE MessageRecipients;
DROP TABLE MessageRecipient;

运行以上代码后,可以得到以下结果:

MessageRecipients表的结果:

MessageId   Recipients
----------- ----------------------------------------------------
1           user1.com; user2.com; user3.com
2           user.com; user.com

MessageRecipient表的结果:

MessageId   Recipient
----------- ----------------
1           user1.com
1           user2.com
1           user3.com
2           user.com
2           user.com

通过使用CROSS APPLY和STRING_SPLIT函数,我们成功地将"Recipients"列中的值拆分为独立的行,并将它们插入到新的"MessageRecipient"表中。这使我们能够更方便地处理和查询这些数据。

0