我有一个包含 200,000 行数据的表。现场与会者已以 csv 格式填充;用逗号分隔符分隔。我想将此字段拆分为最多 7 个不同的列,标记为 Field1、Field2 等。
pkEventBooking Attendees
166935 p1193,c21867,c21827,c21963,c18069,c19222,
195867 p1193,c21827,c22572,c19222,c22573,c21963,c18069,
pkEventBooking Field1 Field2 Field3 Field 4 Field5 Field6 Field7
166935 p1193 c21867 c21827 c21963 c18069 c19222
195867 p1193 c21827 c22572 c19222 c22573 c21963 c18069,
评论太长了。
我倾向于以逗号分隔的格式导出数据并重新导入。 有了这么多数据,您可以执行以下操作:
select * from example
或 select pkEventBooking + ',' + Attendees
顺便说一下,我真的建议您将数据结构为两列:
然后有多个列。
您可以直接在数据库中执行此操作:
insert into EventAttendees(EventBookId, Attendee)
select t.EventBookId, ss.Attendee
from table t cross apply
dbo.SplitString(Attendees) as ss(Attendee);
您可以通过谷歌搜索“SQL Server splitstring”来获取此类函数的定义。
DECLARE @TABLE TABLE (pkEventBooking INT, Attendees NVARCHAR(MAX))
INSERT INTO @TABLE VALUES
(166935 , 'p1193,c21867,c21827,c21963,c18069,c19222'),
(195867 , 'p1193,c21827,c22572,c19222,c22573,c21963,c18069')
;WITH Split_Names (pkEventBooking, Attendees)
AS
(
SELECT pkEventBooking,
CONVERT(XML,'<Attendees><Attendee>'
+ REPLACE(Attendees,',', '</Attendee><Attendee>') + '</Attendee></Attendees>') AS Attendees
FROM @Table
)
SELECT pkEventBooking,
Attendees.value('/Attendees[1]/Attendee[1]','varchar(100)') AS Attendees1,
Attendees.value('/Attendees[1]/Attendee[2]','varchar(100)') AS Attendees2,
Attendees.value('/Attendees[1]/Attendee[3]','varchar(100)') AS Attendees3,
Attendees.value('/Attendees[1]/Attendee[4]','varchar(100)') AS Attendees4,
Attendees.value('/Attendees[1]/Attendee[5]','varchar(100)') AS Attendees5,
Attendees.value('/Attendees[1]/Attendee[6]','varchar(100)') AS Attendees6,
Attendees.value('/Attendees[1]/Attendee[7]','varchar(100)') AS Attendees7
FROM Split_Names
╔════════╦════════════╦════════════╦════════════╦════════════╦════════════╦════════════╦════════════╗
║ Value ║ Attendees1 ║ Attendees2 ║ Attendees3 ║ Attendees4 ║ Attendees5 ║ Attendees6 ║ Attendees7 ║
╠════════╬════════════╬════════════╬════════════╬════════════╬════════════╬════════════╬════════════╣
║ 166935 ║ p1193 ║ c21867 ║ c21827 ║ c21963 ║ c18069 ║ c19222 ║ NULL ║
║ 195867 ║ p1193 ║ c21827 ║ c22572 ║ c19222 ║ c22573 ║ c21963 ║ c18069 ║
╚════════╩════════════╩════════════╩════════════╩════════════╩════════════╩════════════╩════════════╝
另一种选择是使用一些 JSON 与
CROSS APPLY
示例
Select A.[pkEventBooking]
,Pos1 = JSON_VALUE(JS,'$[0]')
,Pos2 = JSON_VALUE(JS,'$[1]')
,Pos3 = JSON_VALUE(JS,'$[2]')
,Pos4 = JSON_VALUE(JS,'$[3]')
,Pos5 = JSON_VALUE(JS,'$[4]')
,Pos6 = JSON_VALUE(JS,'$[5]')
,Pos7 = JSON_VALUE(JS,'$[6]')
From YourTable A
Cross Apply (values ('["'+replace(string_escape([Attendees],'json'),',','","')+'"]') ) B(JS)
结果
样本数据:
DECLARE @TABLE TABLE (pkEventBooking INT, Attendees NVARCHAR(MAX))
INSERT INTO @TABLE VALUES
(166935 , 'p1193,c21867,c21827,c21963,c18069,c19222'),
(195867 , 'p1193,c21827,c22572,c19222,c22573,c21963,c18069')
查询:
SELECT
pkEventBooking,
MAX(CASE WHEN SplitIndex = 1 THEN Value END) AS Column1,
MAX(CASE WHEN SplitIndex = 2 THEN Value END) AS Column2,
MAX(CASE WHEN SplitIndex = 3 THEN Value END) AS Column3,
MAX(CASE WHEN SplitIndex = 4 THEN Value END) AS Column4,
MAX(CASE WHEN SplitIndex = 5 THEN Value END) AS Column5,
MAX(CASE WHEN SplitIndex = 6 THEN Value END) AS Column6,
MAX(CASE WHEN SplitIndex = 7 THEN Value END) AS Column7
FROM (
SELECT
pkEventBooking,
Value,
ROW_NUMBER() OVER (PARTITION BY pkEventBooking ORDER BY (SELECT NULL)) AS SplitIndex
FROM @TABLE
CROSS APPLY STRING_SPLIT(Attendees, ',')
) AS T
GROUP BY pkEventBooking;