如何将表中含多邮箱的列拆分为每行对应单个邮箱的新行?
解决方案
最优方案:用OPENJSON直接解析JSON数组(SQL Server 2016+)
你的邮箱列本质是标准JSON数组,直接用SQL Server内置的OPENJSON函数就能一键拆分,完全不用循环、统计@数量或者拆列UNPIVOT,效率和扩展性都拉满。
假设你的表名为tablename,标识列是identity_id,邮箱列是email_column,直接执行下面的SQL:
SELECT t.identity_id, -- 替换成你实际的标识列名称 JSON_VALUE(j.value, '$') AS email FROM tablename t CROSS APPLY OPENJSON(t.email_column) j WHERE t.email_column <> '[]' -- 过滤空数组的行
- 不管数组里有0个还是几百个邮箱,都能自动处理;
- 空数组的行会被过滤掉,符合你“存在邮箱才生成新记录”的需求;
- 每一行都会关联原表的标识列,完美匹配需求。
兼容低版本SQL Server(2016以下)的方案
如果没法升级版本,只能用字符串拆分的方式处理,先去掉数组的前后括号和引号,再拆分字符串:
WITH SplitEmails AS ( SELECT identity_id, -- 把数组格式转成XML节点,方便拆分 CAST('<e>' + REPLACE(REPLACE(email_column, '["', ''), '"]', '</e><e>') + '</e>' AS XML) AS email_xml FROM tablename WHERE email_column <> '[]' ) SELECT identity_id, -- 提取每个邮箱并去掉多余引号 REPLACE(e.value('.', 'VARCHAR(255)'), '"', '') AS email FROM SplitEmails CROSS APPLY email_xml.nodes('/e') AS emails(e) WHERE e.value('.', 'VARCHAR(255)') <> ''
注意:这个方法如果邮箱里包含<、>这类XML特殊字符会出错,不如OPENJSON稳定,能升级的话优先用第一种方案。
为什么不推荐你的原有思路
- 用WHILE循环逐行拆分:效率极低,数据量大的时候会卡死,而且代码复杂容易出bug;
- 拆列再UNPIVOT:需要提前知道最大邮箱数,一旦有行的邮箱数超过这个数,就会丢失数据,扩展性极差。
内容的提问来源于stack exchange,提问作者caddy
相关产品推荐
相关产品推荐

