将分隔字符串两次拆分为两列表格

问题描述 投票:0回答:2

我有一个具有以下格式的数组:

  • 值用双引号括起来
    ""
  • 各列以逗号分隔
    ,
  • 行之间用分号分隔
    ;
  • 数组被大括号包围
    {}

例如以下字符串...

{"73","2022-09-02 11:42:37.00";"118","2022-08-31 10:41:59.00";"123","2022-09-01 15:26:06.00"}

...将表示一个两列表,第一列的值为 73、118 和 123,2022-09-02 11:42:37.00、2022-08-31 10:41:59.00 和 2022- 09-01 15:26:06.00 在第二栏。

我想将此数组转换为 SQL 中的表。

查看其他几个类似的问题后,我找到了答案,引导我找到了这个解决方案......

DECLARE @array varchar(max)

SET @array = '{"73","2022-09-02 11:42:37.00";"118","2022-08-31 10:41:59.00";"123","2022-09-01 15:26:06.00"}'

SET @array = REPLACE(REPLACE(@array, '{', ''), '}', '')

SELECT Min(CASE b.ordinal WHEN '1' THEN b.value END) 'ID',
       Min(CASE b.ordinal WHEN '2' THEN b.value END) 'Date'
FROM STRING_SPLIT(@array, ';', 1) a
CROSS APPLY STRING_SPLIT(a.value, ',', 1) b
GROUP BY a.ordinal

还有这个选项...

DECLARE @array varchar(max)

SET @array = '{"73","2022-09-02 11:42:37.00";"118","2022-08-31 10:41:59.00";"123","2022-09-01 15:26:06.00"}'

SET @array = REPLACE(REPLACE(@array, '{', ''), '}', '')

SELECT PARSENAME(REPLACE(a.value, ',', '.'), 2) 'ID',
       PARSENAME(REPLACE(a.value, ',', '.'), 1) 'Date'
FROM STRING_SPLIT(@array, ';', 1) a

但是,我对 SQL Server 相当陌生,所以我有一些问题:

  1. 哪种解决方案更可取,为什么?或者说除了这两个还有更好的选择吗?我见过有些人使用 XML,但我对 XML 知之甚少,并且不确定这是否适用于此实现,因为两列都有可变数量的字符。
  2. 为什么 PARSENAME 函数会自动删除值周围的双引号?
  3. 这两个选项都能保持值正确配对吗? (例如,“73”始终与“2022-09-02 11:42:37.00”位于同一行?)
  4. 额外问题:如果这是一个 3+ 列表,一种解决方案会比另一种更好吗?
sql sql-server parsing split
2个回答
0
投票

这是一种使用

string_split()
和一些 JSON 的方法

注意:如果您想要 Pos3(或更多)...只需遵循模式即可。如果没有值,将返回NULL。

示例

Declare @S varchar(max) = '{"73","2022-09-02 11:42:37.00";"118","2022-08-31 10:41:59.00";"123","2022-09-01 15:26:06.00"}'

Select ID   = JSON_VALUE(JS,'$[0]')
      ,Date = JSON_VALUE(JS,'$[1]')
 From  string_split(replace(replace(@S,'{',''),'}',''),';') A
 Cross Apply (values ( ('['+A.Value+']') )) B(JS)

结果

ID      Date
73      2022-09-02 11:42:37.00
118     2022-08-31 10:41:59.00
123     2022-09-01 15:26:06.00

0
投票

将字符串拆分为表的另一个选项是将字符串转换为数组的数组,然后使用 OPENJSON。

/* Demo for linking another table */
DECLARE @tmpTable table(id int, someColumn nvarchar(50))
insert into @tmpTable
values (73, '73 Data')

/* Handle String */
DECLARE @array varchar(max) = '{"73","2022-09-02 11:42:37.00", "more data";
                               "118","2022-08-31 10:41:59.00";
                               "123","2022-09-01 15:26:06.00"}'
SET @array = REPLACE(REPLACE(REPLACE(@array
                , '{', '[[')
                , ';', '],[')
                , '}', ']]')

/* Query */
 SELECT 
    d.ID,
    d."Date",
    d.col3,
    t.someColumn
 FROM OPENJSON(@array) 
 WITH (
    ID int '$[0]',
    "Date" datetime '$[1]',
    col3 nvarchar(50) '$[2]'
 ) d
LEFT JOIN @tmpTable t on t.id = d.ID

使用“WITH”指定列名称、类型和值所在的位置。

我添加了一个表来演示加入。还在第一行中添加了第三列以显示如何处理更多列。

结果

身份证 日期 col3 一些专栏
73 2022-09-02 11:42:37.000 更多数据 73 条数据
118 2022-08-31 10:41:59.000
123 2022-09-01 15:26:06.000
© www.soinside.com 2019 - 2024. All rights reserved.