将分隔的 id 字段转换为它们的漂亮值 - 嵌套是否替换了最佳选项?

Turn a delimited field of ids into their pretty values - Are nested replaces the best option?

考虑以下两个表

客户

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) 但是对于这个问题的范围我或多或少写了伪代码。

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

对于您当前的设计和版本,您最好的选择可能是递归查询以迭代遍历并将客户端 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:

name | new_clients           
:--- | :---------------------
A    | Adam,Steve,Jack,Harvey
B    | Adam,Jack,Harvey      
C    | Steve                 
D    | Adam,Jack