将一个分隔的 id 字段转换为它们的漂亮值 - 嵌套替换是最佳选择吗?

Posted

技术标签:

【中文标题】将一个分隔的 id 字段转换为它们的漂亮值 - 嵌套替换是最佳选择吗?【英文标题】:Turn a delimited field of ids into their pretty values - Are nested replaces the best option? 【发布时间】:2021-03-25 13:50:20 【问题描述】:

考虑以下两个表

客户

ID CLIENT_NAME
1 Adam
2 Steve
3 Jack
4 Harvey

产品

NAME CLIENTS
A 1,2,3,4
B 1,3,4
C 2
D 1,3

如何进行查询,将 Products.Clients 字段替换为 Clients.Client_Name 的分隔字符串而不是 Clients.ID?

所需的查询结果

NAME CLIENTS
A Adam,Steve,Jack,Harvey
B Adam,Jack,Harvey
C Steve
D Adam,Jack

以下使用嵌套替换的方法有效,但对我来说这不是“正确”的方法,特别是因为在我的情况下,每行可能有超过 4 个值 - 有什么更好的方法吗?

SELECT NAME, REPLACE(REPLACE(REPLACE(REPLACE(CLIENTS,1,'Adam'),2,'Steve'),3,'Jack'),4,'Harvey') FROM PRODUCTS

我应该注意,我实际上不会做Replace(clients, 1, 'adam'),而是Replace(clients, 1, SELECT CLIENT_NAME FROM CLIENTS WHERE ID = 1),但对于这个问题的范围,我或多或少地写了伪代码。

【问题讨论】:

在 SQL Server 2014 中,多重替换是一个很好的解决方案。 使用replace 可能会工作一段时间,但12 会发生什么?你真的想要'AdamSteve'吗?如果不考虑分隔符,就会发生这种情况。 @HABO 很好,这使得REPLACE() 成为一个更不理想的“解决方案”。 如果您使用Replace( ',' + Clients + ',', ',1,', ',Adam,' ) ... 并在所有替换后修剪前导和尾随逗号,它可以工作,但是很容易出错。更好的是用逗号分隔它并按照 GMB 的答案处理替换。最好不要在列中存储列表。 【参考方案1】:

您不应该以这种格式存储您的数据。应该有一个单独的表,比如product_clients 来存储两个实体之间的关系,每个不同的产品/客户元组有一行。

对于您当前的设计和版本,您最好的选择可能是递归查询,以迭代遍历并将客户端 ID 替换为相应的名称:

with prod as (
    select 
        p.name, 
        p.clients + ',' as clients,
        cast('' as varchar(max)) as new_clients 
    from products p
    union all
    select 
        p.name, 
        substring(p.clients, charindex(',', p.clients) + 1, len(p.clients)),
        p.new_clients + ',' + c.client_name
    from prod p
    inner join clients c on c.id = left(p.clients, charindex(',', p.clients) - 1)
    where charindex(',', p.clients) > 0
)
select name, stuff(max(new_clients), 1, 1, '') as new_clients 
from prod 
group by name

Demo on DB Fiddle

姓名 |新客户 :--- | :--------- 一个 |亚当、史蒂夫、杰克、哈维 乙|亚当、杰克、哈维 C |史蒂夫 D |亚当,杰克

【讨论】:

感谢您提供的出色 CTE!该表已经存在了一段时间,但我会看看是否可以更改架构以允许您提到的 product_clients 表!

以上是关于将一个分隔的 id 字段转换为它们的漂亮值 - 嵌套替换是最佳选择吗?的主要内容,如果未能解决你的问题,请参考以下文章

将逗号分隔的字符串转换为列表

将三行值转换为列,而不是逗号分隔值

如何将数字转换为 Klaviyo 中的逗号分隔值

React map 方法 Render Input 动态改变值分隔字段

将分隔字段转换为具有名称和值的行

将 wordpress 元数据导入并转换为 ACF 转发器字段