Это не идеально, но , предполагая , что единственное место, где появится пробел (кроме разделителя) в значении date
, вы можете использовать разделитель строк и затем повернуть данные обратно. При этом используется delimitedsplit8k_LEAD
, поскольку важна порядковая позиция:
WITH CTE AS(
SELECT T1.name,
DS.ItemNumber,
DS.Item,
ROW_NUMBER() OVER (PARTITION BY T1.[name] ORDER BY DS.ItemNumber ASC) AS RN
FROM @Table1 T1
CROSS APPLY dbo.delimitedsplit8k_LEAD(T1.[name],' ') DS
WHERE DS.Item <> '')
SELECT MAX(CASE WHEN RN = 1 THEN Item END) + ' ' + MAX(CASE WHEN RN = 2 THEN Item END) AS [Date],
MAX(CASE WHEN RN = 3 THEN Item END) AS [Name],
MAX(CASE WHEN RN = 4 THEN Item END) AS Req,
MAX(CASE WHEN RN = 5 THEN Item END) AS Code
FROM CTE
GROUP BY [Name];
дб <> скрипка
Blarg, если вы не можете создать функцию, вы можете сделать это (но гадость):
DECLARE @Table1 table ([name] varchar(62));
INSERT INTO @Table1 ([name])
VALUES ('2018-08-08 23:02:57,731 INFO [AllRequestInterceptor] CRTST020'),
('2018-08-08 23:03:11,687 INFO [SOAPLoggingHandler] CRTST020'),
('2018-08-08 23:03:02,028 ERROR [AJAXController] CRTST003');
DECLARE @Delimiter char(1) = ' ';
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), --10E+1 or 10 rows
E2 (N) AS
(SELECT 1
FROM E1 AS a,
E1 AS b), --10E+2 or 100 rows
E4 (N) AS
(SELECT 1
FROM E2 AS a,
E2 AS b), --10E+4 or 10,000 rows max
cteTally (N) AS
( --==== This provides the "zero base" and limits the number of rows right up front
-- for both a performance gain and prevention of accidental "overruns"
SELECT 0
UNION ALL
SELECT TOP 62
ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM E4),
cteStart (N1, [name]) AS
( --==== This returns N+1 (starting position of each "element" just once for each delimiter)
SELECT t.N + 1,
T1.[name]
FROM cteTally AS t
CROSS JOIN @Table1 AS T1
WHERE (SUBSTRING(T1.[name], t.N, 1) = @Delimiter
OR t.N = 0)),
Splits AS
(SELECT s.[name],
ROW_NUMBER() OVER (ORDER BY s.N1) AS ItemNumber,
SUBSTRING(s.[name], s.N1, ISNULL(NULLIF((LEAD(s.N1, 1, 1) OVER (PARTITION BY s.[name] ORDER BY s.N1) - 1), 0) - s.N1, 8000)) AS item
FROM cteStart AS s),
CTE AS
(SELECT name,
ItemNumber,
item,
ROW_NUMBER() OVER (PARTITION BY [name] ORDER BY ItemNumber ASC) AS RN
FROM Splits
WHERE item <> '')
SELECT MAX(CASE WHEN RN = 1 THEN item END) + ' ' + MAX(CASE WHEN RN = 2 THEN item END) AS [Date],
MAX(CASE WHEN RN = 3 THEN item END) AS [Name],
MAX(CASE WHEN RN = 4 THEN item END) AS Req,
MAX(CASE WHEN RN = 5 THEN item END) AS Code
FROM CTE
GROUP BY [name];