如何将值分隔成行

huangapple go评论61阅读模式
英文:

How to separate values ​into rows

问题

我有这样的数据:

ID 角色 控制单元 用户ID
00196 SPV / TL / CS 00G (nol) 0016506 , 0016551 , 0016541
00237 SPV,CS, TL 14I 1458506, 1458541
00196 SPV / CS / TL 0C3 0435506, 0435541, 0435551

我想根据它们各自的角色分离用户ID,使其看起来像这样:

ID 角色 控制单元 用户ID
00196 SPV 00G (nol) 0016506
00196 TL 00G (nol) 0016551
00196 CS 00G (nol) 0016541
00237 SPV 14I 1458506
00237 CS 14I 1458541
00237 TL 14I NULL
00196 SPV 0C3 0435506
00196 CS 0C3 0435541
00196 TL 0C3 0435551

用户ID的规则如下:

  • XXXX506 - XXXX510 = SPV
  • XXXX541 - XXXX550 = CS
  • XXXX551 - XXXX560 = TL

每个用户ID的前四位数字是分行代码,所以可以忽略它们。只需取每个角色的最后三个数字。

英文:

I have data like this:

ID Role Control Unit User ID
00196 SPV / TL / CS 00G (nol) 0016506 , 0016551 , 0016541
00237 SPV,CS, TL 14I 1458506, 1458541
00196 SPV / CS / TL 0C3 0435506, 0435541, 0435551

I want to separate the User ID based on their respective roles, so it looks like this:

ID Role Control Unit User ID
00196 SPV 00G (nol) 0016506
00196 TL 00G (nol) 0016551
00196 CS 00G (nol) 0016541
00237 SPV 14I 1458506
00237 CS 14I 1458541
00237 TL 14I NULL
00196 SPV 0C3 0435506
00196 CS 0C3 0435541
00196 TL 0C3 0435551

The rules of User IDs is:

  • XXXX506 - XXXX510 = SPV
  • XXXX541 - XXXX550 = CS
  • XXXX551 - XXXX560 = TL

The first four digits of each User ID are the branch code, so you can ignore that. Just take the last three numbers for each role.

答案1

得分: 2

请尝试以下的解决方案。

它使用JSON来对标记进行标记

SQL

-- DDL和示例数据填充,开始
DECLARE @tbl table (ID CHAR(5), ROLE VARCHAR(200), ControlUnit VARCHAR(20), UserID VARCHAR(200))
INSERT @tbl (ID, Role, ControlUnit, UserID) VALUES
('0019', 'SPV / TL / CS', '00G (nol)', '0016506 , 0016551 , 0016541'),
('0023', 'SPV / CS / TL', '14I', '1458506, 1458541, 0435551'),
('0019', 'SPV / CS / TL', '0C3', '0435506, 0435541, 0435551');
-- DDL和示例数据填充,结束

;WITH rs AS
(
SELECT ID, ControlUnit, Role, UserID
, s = '["' + REPLACE(STRING_ESCAPE([Role],'json'), '/', '","') + '"]'
, s1 = '["' + REPLACE(STRING_ESCAPE(UserID,'json'), ',', '","') + '"]'
FROM @tbl
)
SELECT ID, TRIM([Role].[value]) AS [Role], ControlUnit, TRIM(UserID.[value]) AS UserID
FROM rs
CROSS APPLY OPENJSON (s, N'$') AS [Role]
CROSS APPLY OPENJSON (s1, N'$') AS UserID
WHERE [Role].[key] = UserID.[key];

Output

ID Role ControlUnit UserID
0019 SPV 00G (nol) 0016506
0019 TL 00G (nol) 0016551
0019 CS 00G (nol) 0016541
0023 SPV 14I 1458506
0023 CS 14I 1458541
0023 TL 14I 0435551
0019 SPV 0C3 0435506
0019 CS 0C3 0435541
0019 TL 0C3 0435551
英文:

Please try the following solution.

It is using JSON to tokenize string of tokens.

SQL

-- DDL and sample data population, start
DECLARE @tbl table (ID CHAR(5), ROLE VARCHAR(200), ControlUnit VARCHAR(20), UserID VARCHAR(200))
INSERT @tbl (ID, Role, ControlUnit, UserID) VALUES
('0019', 'SPV / TL / CS', '00G (nol)',	'0016506 , 0016551 , 0016541'),
('0023', 'SPV / CS / TL', '14I',		'1458506, 1458541, 0435551'),
('0019', 'SPV / CS / TL', '0C3',		'0435506, 0435541, 0435551');
-- DDL and sample data population, end

;WITH rs AS 
(
     SELECT ID, ControlUnit, Role, UserID
         , s = '["' + REPLACE(STRING_ESCAPE([Role],'json'), '\/', '","') + '"]'
         , s1 = '["' + REPLACE(STRING_ESCAPE(UserID,'json'), ',', '","') + '"]'
     FROM @tbl
)
SELECT ID, TRIM([Role].[value]) AS [Role], ControlUnit, TRIM(UserID.[value]) AS UserID
FROM rs
	CROSS APPLY OPENJSON (s, N'$') AS [Role]
	CROSS APPLY OPENJSON (s1, N'$') AS UserID
WHERE [Role].[key] = UserID.[key];

Output

ID Role ControlUnit UserID
0019 SPV 00G (nol) 0016506
0019 TL 00G (nol) 0016551
0019 CS 00G (nol) 0016541
0023 SPV 14I 1458506
0023 CS 14I 1458541
0023 TL 14I 0435551
0019 SPV 0C3 0435506
0019 CS 0C3 0435541
0019 TL 0C3 0435551

答案2

得分: 1

你可以使用STRING_SPLIT()函数,只需确保标准化你的分隔符-

  • 决定一种分隔符的类型和样式,例如逗号
  • 要么确保在数据库中始终只使用此分隔符
  • 要么您可以在查询中使用REPLACE()函数来修复它

然后,您可以像这样使用STRING_SPLIT()函数:

SELECT T.ID AS ID,
       Roles.RoleName AS Role,
       T.[Control Unit] AS [Control Unit],
       UserIds.UserId AS [User ID]
FROM UsersToRoles AS T
OUTER APPLY
(
    SELECT S.ordinal AS RoleOrder,
           S.[value] AS RoleName
    FROM STRING_SPLIT(T.[Role], ',') AS S
) AS Roles
OUTER APPLY
(
    SELECT S.ordinal AS UserIdOrder,
           S.[value] AS UserId
    FROM STRING_SPLIT(T.[User ID], ',') AS S
) AS UserIds
WHERE UserIds.UserIdOrder = Roles.RoleOrder
英文:

You can use STRING_SPLIT() function,
just make sure to normalize your separators-

  • decide on one type and style of separator, for example comma
  • either make sure in DB to always use only this separator
  • or you can use REPLACE() functions in your query to fix it

Then you can use the STRING_SPLIT() function like this:

SELECT	T.ID				AS	ID,
		Roles.RoleName		AS	[Role],
		T.[Control Unit]	AS	[Control Unit],
		UserIds.UserId		AS	[User ID]

FROM	UsersToRoles		AS	T
OUTER APPLY
(
	SELECT	S.ordinal		AS	RoleOrder,
			S.[value]		AS	RoleName
	FROM	STRING_SPLIT(T.[Role], ',')	AS	S
)	AS	Roles
OUTER APPLY
(
	SELECT	S.ordinal		AS	UserIdOrder,
			S.[value]		AS	UserId
	FROM	STRING_SPLIT(T.[User ID], ',')	AS	S
)	AS	UserIds
WHERE	UserIds.UserIdOrder =	Roles.RoleOrder

huangapple
  • 本文由 发表于 2023年4月4日 16:54:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75927373.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定