SQL:使用 SQL 将两个逗号分隔的字符串拆分为单独的索引行
Posted
技术标签:
【中文标题】SQL:使用 SQL 将两个逗号分隔的字符串拆分为单独的索引行【英文标题】:SQL: Split two comma separated strings into separate indexed rows using SQL 【发布时间】:2018-01-15 07:44:58 【问题描述】:我存储的数据使我的查询返回以下内容:
EntryNum FieldNames FootnoteIDs
1 FieldA, FieldA, FieldB F1, F3, F2
2 FieldA, FieldA, FieldB F1, F4, F2
3 FieldB, FieldC, FieldD F1, F12, F13
我想按如下方式返回:
EntryNum FieldName FootnoteID
1 FieldA F1
1 FieldA F3
1 FieldB F2
2 FieldA F1
2 FieldA F4
2 FieldB F2
3 FieldB F1
3 FieldC F12
3 FieldD F13
用于此的 SQL 会是什么样子?不使用用户定义的函数或 SPLIT_STRING 是否可行?
我找到的最接近解决方案的是: Split comma separated string table row into separate rows using TSQL,但这没有我需要的双重分裂行为。更多详细信息 a) 每个条目的字段数或每个条目的脚注 ID 没有限制,并且 b) 我需要匹配的只是字段名称和脚注 ID 的顺序。
【问题讨论】:
看起来这里已经回答了这个问题,该技术应该能够为您需要的多列提供相应的逐行结果。 ***.com/questions/19073500/… 我已经看过那个答案,但它不适用于这个用例。它返回一个包含所有逗号分隔项目的单列,而我需要将两个不同字段中的项目相关地放入行中。 对于 SQL Server:考虑他在此处详细介绍的各种用户定义函数方法sqlperformance.com/2012/07/t-sql-queries/split-strings 我正在处理的服务器不允许创建/使用用户定义的函数,所以很遗憾,这在这里是不可能的。 【参考方案1】:当问题被标记为 MySQL 时提供此答案。
您的预期结果要求 fieldname 与 FootnoteID 存在一对一的关系,因此定位一个连接列的每个部分的逻辑与第二个所需的逻辑相同。换句话说:如果您的数据在两个逗号分隔的列中具有相同数量的部分,则可以使用一种方法来拆分两者:
CREATE TABLE Table1
(`EntryNum` int, `FieldNames` varchar(22), `FootnoteIDs` varchar(12))
;
INSERT INTO Table1
(`EntryNum`, `FieldNames`, `FootnoteIDs`)
VALUES
(1, 'FieldA, FieldA, FieldB', 'F1, F3, F2'),
(2, 'FieldA, FieldA, FieldB', 'F1, F4, F2'),
(3, 'FieldB, FieldC, FieldD', 'F1, F12, F13')
;
查询 1:
SELECT
t.EntryNum
, SUBSTRING_INDEX(SUBSTRING_INDEX(t.FieldNames, ',', n.n), ',', -1) FieldName
, SUBSTRING_INDEX(SUBSTRING_INDEX(t.FootnoteIDs, ',', n.n), ',', -1) FootnoteID
FROM table1 t
CROSS JOIN (
SELECT a.N + b.N * 10 + 1 n
FROM (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
CROSS JOIN (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
) n
WHERE n.n <= 1 + (LENGTH(t.FieldNames) - LENGTH(REPLACE(t.FieldNames, ',', '')))
order by t.EntryNum, n.n
看到这个SQL Fiddle
| EntryNum | FieldName | FootnoteID |
|----------|-----------|------------|
| 1 | FieldA | F1 |
| 1 | FieldA | F3 |
| 1 | FieldB | F2 |
| 2 | FieldA | F1 |
| 2 | FieldA | F4 |
| 2 | FieldB | F2 |
| 3 | FieldB | F1 |
| 3 | FieldC | F12 |
| 3 | FieldD | F13 |
注意上面的查询是SQL split comma separated row 答案的派生词,该答案指的是永久“计数表”而不是如上所述的动态子查询 (n) 的好处。
【讨论】:
抱歉,我错误地将我的问题标记为针对 mysql,而实际上我使用的是 SQL Server。 SQL Server 中似乎不存在 SUBSTRING_INDEX 函数。不过,这看起来是正确的想法! SQL Server 是否有等效的实现? 这是一个相当错误的标签! (请在以后仔细检查)。它可以在 SQL Server 中实现 - 但您使用的是什么版本(这可能会有所不同)。注意:研究“拆分字符串函数 tsql”。从 SQL Server 2016 开始,有一个内置函数 docs.microsoft.com/en-us/sql/t-sql/functions/… 当我运行服务器版本查询时,它告诉我我正在使用 SQL Server 2016,但也无法识别 split_string 函数。有谁知道为什么会这样?我检查了兼容性级别,它说它是 130。 是错字吗?函数是 string_split 而不是 split_string。以上是关于SQL:使用 SQL 将两个逗号分隔的字符串拆分为单独的索引行的主要内容,如果未能解决你的问题,请参考以下文章
如何根据一个字段是不是包含oracle sql中的逗号分隔字符串将单行拆分为多行?