Разделить строковый столбец цифр c на несколько столбцов после каждой запятой - PullRequest
0 голосов
/ 29 апреля 2020

split the string in multiple columns in a table for multiple columns. like i got this output from string aggregation Мне нужно преобразовать это в три столбца, длина не является stati c, так как вышеуказанные числа приходят на основе расчета.

Ответы [ 3 ]

1 голос
/ 29 апреля 2020

В SQL Server 2016 вы можете использовать STRING_SPLIT для разделения строки (после удаления окружающих ( и )), а затем PIVOT, что приводит к столбцам:

WITH CTE AS (
  SELECT value, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rn
  FROM STRING_SPLIT(REPLACE(REPLACE('(0.0000, 3546.0000, 253422.000)', '(', ''), ')', ''), ',')
)
SELECT [1] AS Val1,
       [2] AS Val2,
       [3] AS Val3
FROM CTE
PIVOT (
  MAX(value)
  FOR rn IN ([1], [2], [3])
) p

Вывод:

Val1        Val2        Val3
0.0000      3546.0000   253422.000

Демонстрация по dbfiddle

Чтобы сделать это со значениями в таблице, вам просто нужно CROSS APPLY STRING_SPLIT до столик внутри CTE. Например, если столбец называется exclusion в таблице с именем data:

WITH CTE AS (
  SELECT exclusion, value, ROW_NUMBER() OVER (PARTITION BY exclusion ORDER BY (SELECT NULL)) AS rn
  FROM data
  CROSS APPLY STRING_SPLIT(exclusion, ',')
)
SELECT exclusion,
       [1] AS Val1,
       [2] AS Val2,
       [3] AS Val3
FROM CTE
PIVOT (
  MAX(value)
  FOR rn IN ([1], [2], [3])
) p

Демонстрация на dbfiddle

1 голос
/ 29 апреля 2020

Согласно документам STRING_SPLIT() не гарантирует возврата ожидаемого порядка сортировки.

Выходные строки могут быть в любом порядке . Не гарантируется, что порядок соответствует порядку подстрок во входной строке.

Прочитайте это здесь: STRING_SPLIT () документация

Попробуйте это JSON подхода:

DECLARE @yourString NVARCHAR(100)=N'0.0000, 3546.0000, 253422.000';

- просто вернуть массив как производную таблицу

SELECT *
FROM OPENJSON(CONCAT(N'[',@yourString,']'))

- использовать неявное вращение с помощью предложения WITH (требуются двойные скобки массива)

SELECT *
FROM OPENJSON(CONCAT(N'[[',@yourString,']]'))
WITH (val1 FLOAT '$[0]'
     ,val2 FLOAT '$[1]'
     ,val3 FLOAT '$[2]')

ОБНОВЛЕНИЕ

Здесь я использую образец вашего другого вопроса. Пожалуйста, - для вашего следующего вопроса - не размещайте фотографию. Никто не хочет вводить значения.

Лучше всего использовать DDL и INSERT, как я это делаю здесь:

- Определить таблицу макетов для имитации вашей проблемы и вставить образец данные

DECLARE @tbl TABLE(ID INT,[TYPE] VARCHAR(100),prouctValues VARCHAR(100),subproValues VARCHAR(100),Amount VARCHAR(100));
INSERT INTO @tbl VALUES
 (23844,'12, 19','0.0000, 0.0000','0.0000, 0.0000','0.0000, 0.0000,37464.083')
,(25397,'1, 3,26','0.0000, 0.0000,2.345','0.0000,0.2345, 0.0000 ','25455.6800, 0.0000');

- запрос

SELECT t.ID
      ,AllTypes.*
      ,AllPvals.* 
      ,AllSPvals.* 
      ,AllAmts.*
FROM @tbl t 
CROSS APPLY OPENJSON(CONCAT('[[',t.[TYPE],']]'))       WITH(t1      INT           '$[0]'
                                                           ,t2      INT           '$[1]'
                                                           ,t3      INT           '$[2]') AllTypes
CROSS APPLY OPENJSON(CONCAT('[[',t.prouctValues,']]')) WITH(pval_1  DECIMAL(10,4) '$[0]'
                                                           ,pval_2  DECIMAL(10,4) '$[1]'
                                                           ,pval_3  DECIMAL(10,4) '$[2]') AllPVals
CROSS APPLY OPENJSON(CONCAT('[[',t.subproValues,']]')) WITH(spval_1 DECIMAL(10,4) '$[0]'
                                                           ,spval_2 DECIMAL(10,4) '$[1]'
                                                           ,spval_3 DECIMAL(10,4) '$[2]') AllSPVals
CROSS APPLY OPENJSON(CONCAT('[[',t.Amount,']]'))       WITH(amt_1   DECIMAL(10,4) '$[0]'
                                                           ,amt_2   DECIMAL(10,4) '$[1]'
                                                           ,amt_3   DECIMAL(10,4) '$[2]') AllAmts;

результат

+-------+----+----+------+--------+--------+--------+---------+---------+---------+------------+--------+------------+
| ID    | t1 | t2 | t3   | pval_1 | pval_2 | pval_3 | spval_1 | spval_2 | spval_3 | amt_1      | amt_2  | amt_3      |
+-------+----+----+------+--------+--------+--------+---------+---------+---------+------------+--------+------------+
| 23844 | 12 | 19 | NULL | 0.0000 | 0.0000 | NULL   | 0.0000  | 0.0000  | NULL    | 0.0000     | 0.0000 | 37464.0830 |
+-------+----+----+------+--------+--------+--------+---------+---------+---------+------------+--------+------------+
| 25397 | 1  | 3  | 26   | 0.0000 | 0.0000 | 2.3450 | 0.0000  | 0.2345  | 0.0000  | 25455.6800 | 0.0000 | NULL       |
+-------+----+----+------+--------+--------+--------+---------+---------+---------+------------+--------+------------+
0 голосов
/ 29 апреля 2020

Строковые операции болезненны на SQL Сервере. Вот один из методов:

select replace(v1.el, '(', '') as column1, v2.el as column2,
       replace(v2.rest, ')', '') as column3
from t cross apply
     (values (left(t.derived, charindex(',', t.derived) - 1),
              stuff(t.derived, 1, charindex(',', t.derived), '')
             )
     ) v1(el, rest) cross apply
     (values (left(v.rest, charindex(',', v.rest) - 1),
              stuff(v.rest, 1, charindex(',', v.rest), '')
             )
     ) v2(el, rest);
...