【发布时间】:2022-01-22 08:07:03
【问题描述】:
我有一张这样的桌子:
| Id | Description | Recipient |
|---|---|---|
| 1 | lipsum | 35235 |
| 2 | dolor est | 123, 456, 2432 |
| 3 | Lorem Ipsum | 143243, 34, 2344 |
我想要这样的输出:
| Id | Description | Recipient | RecipientId |
|---|---|---|---|
| 1 | lipsum | 35235 | 35235 |
| 2 | dolor est | 123, 456, 2432 | 123 |
| 3 | Lorem Ipsum | 143243, 34, 2344 | 143243 |
我需要使用收件人 ID 加入一个收件人数据表。值得庆幸的是,行中每个收件人的必要数据都是相同的,所以我只需要一个 ID。我想返回相同的数据,除了收件人列中的每一行只有第一个(甚至只有一个)ID。
我现在的方法是这样的:
SELECT Id,
Description,
Recipient,
MAX(value) as RecipientID
FROM msg
CROSS APPLY STRING_SPLIT(Recipient, ',')
GROUP BY Id, Description, Recipient
虽然此方法为我提供了一个收件人 ID,然后我可以将其用作键,但由于收件人列可能在一个单元格中包含大于 2k 的 ID 列表,因此需要很长时间。
我尝试了一种 REGEX 解决方案来提取分隔符前面的起始数字集,但我找不到不用作过滤器的方法。
如果 SQL Server 有一个像 MySQL 的 SUBSTRING_INDEX 这样的函数来获取第一个 ID,那就太好了,但它没有。
我怎样才能只返回每个收件人单元格的一个元素而不必执行CROSS APPLY 和聚合?
【问题讨论】:
-
请查看stackoverflow.com/questions/3653462/… 并规范化您的表格
-
您可以使用
CHARINDEX()和SUBSTRING()来执行此操作,例如CASE WHEN CHARINDEX(',', Recipient) > 0 THEN SUBSTRING(Recipient, 1, CHARINDEX(',', Recipient)-1) ELSE Recipient END- Example on db<>fiddle。但老实说,只需修复您的架构。 SQL 已经具有存储数据列表的理想结构,它们被称为表。存储分隔列表几乎从来都不是正确的解决方案。 -
我同意架构只需要更新,但我只是一个低级的数据分析师,对如何构建数据库架构没有发言权。我只是负责制作有效的报告。
标签: sql sql-server tsql