如何在 SQL 的单列中使用多个 ID 从 table 获取值?

How to get values from table using multiple ID's in single column in SQL?

我正在使用现有的存储过程。在那里,他们使用 select 查询获取一些数据。现在我正在尝试获取更多数据。我遇到的问题是,我用来从另一个 table 获取数据的列中保存了多个 Id,中间用逗号 (,) 保存。

2 tables 的程序为 Tbl_av,Tbl_aa.

我在 Tbl_av 中有一列作为 processId 在 Varchar[=60= 中] 并存储 1,2,4 等数据。(即,它存储进程的 ID)。

现在我正在尝试使用 table [=45] 下的此 ProcessId 从另一个 table Tbl_Process 获取进程名称=]Tbl_av。在 table、 中,进程 ID 是唯一的,并且是整数。

Tbl_Process如下:

Tbl_av如下:

我有以下几部分程序:

SET @strQuery= 'SELECT isnull(av.ID, 0) AS ID
      ,isnull(ItemNumber, '''') AS Number  
      ,isnull(av.ItemName,'''') as Item Name
      ,av.Description
      ,(select top 1 Name from TBL_Names where Id =aa.id)as Person Incharge from Tbl_AV av, Tbl_aa aa WHERE av.S_number = aa.S_number'

现在我要做的是,我需要使用 Tbl_av[从 Tbl_Process 中获取进程名称 ProcessId's inside the procedure.

我不知道如何实现它,因为它的两列都是不同的数据类型,并且在一列中保存了超过 1 个 ID

注意:我们可以简单地实现这一点 'SELECT Process_Name from Tbl_Process WHERE Id in (av.ProcessId)' - 但是这样做会以列格式显示数据。 我希望数据被 select 编辑,就好像 Id 是 1,2 意味着我希望我的输出为 Process_Name = Item 1,Item 2.

请帮忙。

需要两个技巧。一种是根据 comma-separated ID 列表加入。这很容易做得不好,导致不需要的匹配,例如 1 和 2 匹配 12。Stephen Jennings 引用的文章有一些很好的可靠解决方案。

第二个是将一组结果连接成一个字符串。对于最新版本的 SQL 服务器,STRING_AGG 是首选解决方案。对于旧版本(例如 2014),最常用的方法是“FOR XML”技巧。

我结合了以下两种技术。

DECLARE @Tbl_Process TABLE(ID INT, process_Name VARCHAR(100))
INSERT @Tbl_Process
VALUES (1, 'Item 1'), (2, 'Item 2'), (3, 'Item 3'), (4, 'Item 4'), (5, 'Item 5'), (12, 'Item 12')

DECLARE @Tbl_av TABLE(ID INT, ProcessId VARCHAR(100))
INSERT @Tbl_av
VALUES (1, '1,3,5'), (2, '2,4'), (3, '1,2,3'), (4, '1,5'), (5, ''), (6, '3,4,12')

SELECT AV.*, PL.*
FROM @Tbl_av AV
CROSS APPLY (
    SELECT ISNULL(STUFF(
        (
            SELECT ',' + P.process_Name
            FROM @Tbl_Process P
            --(bad) WHERE CHARINDEX(CONVERT(VARCHAR, P.ID), AV.ProcessId) > 0
            WHERE ',' + AV.ProcessId + ',' LIKE '%,' + CONVERT(VARCHAR, P.ID) + ',%'
            ORDER BY P.ID -- alternately ORDER BY P.process_Name
            FOR XML PATH(''), TYPE
        ).value('text()[1]','nvarchar(max)')
    , 1, 1, '')
    , '(none)')
    AS Process_Names
) PL

结果

ID ProcessId Process_Names
1 1,3,5 Item 1,Item 3,Item 5
2 2,4 Item 2,Item 4
3 1,2,3 Item 1,Item 2,Item 3
4 1,5 Item 1,Item 5
5 (none)
6 3,4,12 Item 3,Item 4,Item 12

FOR XML PATH('') 技巧导致结果连接成单个 XML 字符串,没有标签。 , TYPE.value('text()[1]','nvarchar(max)') 一起安全地提取结果文本,撤销任何 XML 特定文本编码,例如 &<>。 STUFF() 删除前导逗号,如果没有值,ISNULL() 提供默认值。

有关 FOR XML 技巧如何工作的更多信息,请参阅 How Stuff and 'For Xml Path' work in SQL Server?

如果您更喜欢 comma-space 列表分隔符,您可以更新 ',',但还需要调整 STUFF 以去除两个字符而不是一个。

交叉应用的内容可以直接移动到 SELECT 子句中,但作为样式问题,CROSS APPLY 允许将复杂逻辑与查询的其余部分分开。