我有以下数据
我想将列转换为行
我使用了以下Query ::
Select Distinct [ApplicantID],
Split.a.value('.', 'VARCHAR(100)') AS Subjects,
hoursperweek,[Days],[Time]
From ( Select
Cast ('<M>' + REPLACE([Subjects], ',', '</M><M>') + '</M>' AS XML)
AS Subjects , ApplicantID, hoursperweek,[Days],[Time]
From [dbo].[Progrm])
AS A CROSS APPLY Subjects.nodes ('/M') AS Split(a)
它给我以下结果
但是我想分开主题,每周几小时,几天,几天。我怎么能这样做?
ApplicantID Subjects HoursPerWeek Days Time
1 a 12 Sun 12:45:12
1 b 25 Mon 14:45:12
答案 0 :(得分:2)
这是一个将逗号分隔值拆分为行
的函数CREATE FUNCTION dbo.Splitstrings (@List NVARCHAR(MAX),
@Delimiter NVARCHAR(255))
RETURNS @split_tab TABLE (
RN INT IDENTITY(1, 1),
SPLIT_VAL VARCHAR(100))
WITH SCHEMABINDING
AS
BEGIN ;
;WITH E1(N)
AS (SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1),
E2(N) AS (SELECT 1 FROM E1 a,E1 b),
E4(N) AS (SELECT 1 FROM E2 a, E2 b),
E42(N) AS (SELECT 1 FROM E4 a, E2 b),
cteTally(N)
AS (SELECT 0
UNION ALL
SELECT TOP (Datalength(Isnull(@List, 1))) Row_number()OVER (
ORDER BY (SELECT NULL))
FROM E42),
cteStart(N1)
AS (SELECT t.N + 1
FROM cteTally t
WHERE ( Substring(@List, t.N, 1) = @Delimiter
OR t.N = 0 ))
INSERT INTO @split_tab
SELECT SPLIT_VAL= Substring(@LIST, S.N1, Isnull(NULLIF(Charindex(@DELIMITER, @LIST, S.N1), 0) - S.N1, 8000))
FROM CTESTART S;
RETURN
END
现在分割数据的丑陋代码
;WITH data
AS (SELECT 1 ApplicantID,
'a,b' Subjects,
'12,25' HoursPerWeek,
'sun,mon' Days,
'12:45:12,14:45:12' Time),
sub
AS (SELECT RN,
ApplicantID,
Subjects=SPLIT_VAL
FROM data
CROSS apply Splitstrings (Subjects, ',')),
HPW
AS (SELECT RN,
ApplicantID,
HoursPerWeek=SPLIT_VAL
FROM data
CROSS apply Splitstrings (HoursPerWeek, ',')),
Days
AS (SELECT RN,
ApplicantID,
Days=SPLIT_VAL
FROM data
CROSS apply Splitstrings (Days, ',')),
Time
AS (SELECT RN,
ApplicantID,
Time=SPLIT_VAL
FROM data
CROSS apply Splitstrings (Time, ','))
SELECT D.APPLICANTID,
S.SUBJECTS,
H.HOURSPERWEEK,
DA.DAYS,
T.TIME
FROM DATA D
FULL OUTER JOIN SUB S
ON D.APPLICANTID = S.APPLICANTID
FULL OUTER JOIN HPW H
ON D.APPLICANTID = H.APPLICANTID
AND H.RN = S.RN
FULL OUTER JOIN DAYS DA
ON D.APPLICANTID = DA.APPLICANTID
AND DA.RN = COALESCE(S.RN, H.RN)
FULL OUTER JOIN TIME T
ON D.APPLICANTID = T.APPLICANTID
AND T.RN = COALESCE(S.RN, H.RN, DA.RN)
<强>结果:强>
╔═════════════╦══════════╦══════════════╦══════╦══════════╗
║ APPLICANTID ║ SUBJECTS ║ HOURSPERWEEK ║ DAYS ║ TIME ║
╠═════════════╬══════════╬══════════════╬══════╬══════════╣
║ 1 ║ a ║ 12 ║ sun ║ 12:45:12 ║
║ 1 ║ b ║ 25 ║ mon ║ 14:45:12 ║
╚═════════════╩══════════╩══════════════╩══════╩══════════╝
这就是我们永远不应该将逗号分隔值存储到单个列中的原因。当你想解析数据时,事情变得困难,我们需要这些丑陋的代码来解析数据