Разделить строку с различными факторами в SQL Server - PullRequest
1 голос
/ 31 марта 2019

Сериализованные данные хранятся в столбце.Я хочу преобразовать значения списка во временную таблицу.Но в значениях строк есть более одного фактора, например

["2","3","4"]
["1","2","3"]
[]
["Select option B","Select option C","Select option D"]
["Moderate","Heavy","Heavy, Big & Abnormal"]

Если я проанализирую двойные кавычки, то запятая в строковом значении создаст это как другую сущность.

Ответы [ 2 ]

2 голосов
/ 01 апреля 2019

Это помечено [sql-server-2012] - как жаль ... С v2016 + вы могли бы вызывать STRING_SPLIT или даже методы JSON ... Следующее является довольно хакерским подходом, но работает - по крайней мере, с вашими предоставленными тестовыми данными ...

Создайте макет-таблицу (пожалуйста, сделайте это самостоятельно в следующий раз).

DECLARE @tbl TABLE(ID INT IDENTITY, YourString VARCHAR(100));
INSERT INTO @tbl VALUES
 ('["2","3","4"]')
,('["1","2","3"]')
,('[]')
,('["Select option B","Select option C","Select option D"]')
,('["Moderate","Heavy","Heavy, Big & Abnormal"]');

- это запрос:

SELECT t.ID
      --,t.YourString 
      ,C.Separated.value('text()[1]','nvarchar(max)') AS Parted
FROM @tbl t
CROSS APPLY(SELECT REPLACE(REPLACE(REPLACE(YourString,'"','"'),'["',''),'"]','')) A(replaced)
CROSS APPLY(SELECT CAST('<x>' + REPLACE((SELECT A.replaced [*] FOR XML PATH('')),'","','</x><x>') + '</x>' AS XML)) B(casted)
CROSS APPLY B.casted.nodes('/x') C(Separated);

Идея вкратце:

Прежде всего я использую несколько REPLACE() для очистки и согласования ваших данных. Затем второй CROSS APPLY будет использовать XML для разделения ваших строк на , заменяя каждую запятую вместе с кавычками! на XML-теги. Таким образом мы можем предотвратить расщепление по внутренним запятым. Но прежде мы должны использовать FOR XML в исходной строке, чтобы разрешить такие символы, как & в Big & Abnormal. Остальное довольно просто XPath/XQuery.

Результат

+----+-----------------------+
| ID | Parted                |
+----+-----------------------+
| 1  | 2                     |
+----+-----------------------+
| 1  | 3                     |
+----+-----------------------+
| 1  | 4                     |
+----+-----------------------+
| 2  | 1                     |
+----+-----------------------+
| 2  | 2                     |
+----+-----------------------+
| 2  | 3                     |
+----+-----------------------+
| 3  | []                    |
+----+-----------------------+
| 4  | Select option B       |
+----+-----------------------+
| 4  | Select option C       |
+----+-----------------------+
| 4  | Select option D       |
+----+-----------------------+
| 5  | Moderate              |
+----+-----------------------+
| 5  | Heavy                 |
+----+-----------------------+
| 5  | Heavy, Big & Abnormal |
+----+-----------------------+
0 голосов
/ 31 марта 2019

Использование STRING_SPLIT с порядковым номером:

WITH cte AS (
  SELECT value AS val, ROW_NUMBER() OVER(ORDER BY 1/0) AS ord
  FROM STRING_SPLIT(TRIM('[]' FROM '["2","3","4"]'), ',')
), cte2 AS (
  SELECT value AS val, ROW_NUMBER() OVER(ORDER BY 1/0) AS ord
  FROM STRING_SPLIT(TRIM('[]' FROM '["Select option B","Select option C","Select option D"]'), ',')
)
-- ...
SELECT cte.val, cte2.val
FROM cte
LEFT JOIN cte2
  ON cte.ord = cte2.ord
-- ...

ДБ <> Fiddle demo

Для SQL Server вы можете использовать пользовательскую функцию разделения: STRING_SPLIT в SQL Server 2012

...