在Varchar上左加入INT

Rus*_*ter -1 t-sql sql-server int varchar left-join

我正在编写一份报告,以显示客户在家中建设时需要的功能.我想离开连接2个表但数据的存储方式使我很难进行连接.

表1 tbl_Main_Holding有一个名为Requirements的字段,数据存储为varchar,可以有多个值,如1,4,7

1 = "Eco-Build"
4 = "Conservatory"
7 = "Basement"
Run Code Online (Sandbox Code Playgroud)

表2 [tbl_Features]具有字段ID(INT)和描述(Varchar)

SELECT * FROM dbo.tbl_Main_Holding AS rm 
LEFT JOIN [dbo].[tbl_Features] AS f
ON rm.Requirements = f.id
Run Code Online (Sandbox Code Playgroud)

下面的连接不会工作,因为我需要将varchar转换为INT但是这不是我的问题我的问题是我如何显示已选择多个功能的客户端的结果,这个离开加入如何工作?我使用SQL Server 2008,两个表的数据都存储起来. 在此输入图像描述 在此输入图像描述

Gar*_*thD 5

第一步是找到设计这个桌子结构的人(即使是你),然后用棍子将它们围绕头部敲打.

第2步是重新设计表,这里需要一个联结表,而不是将多个整数填充到单个varchar列中.为了在第二步结束时做好准备,你应该再次用棍子击中原设计师.

CREATE TABLE tbl_Main_Holding_Requirements
(
    MainHoldingID INT NOT NULL, --FK TO `tbl_main_Holding`
    FeatureID INT NOT NULL -- FK TO Require `tbl_Features`
);
Run Code Online (Sandbox Code Playgroud)

现在,每个需求代表此表中的一行,而不是列表中的新项,因此您的连接现在很简单:

SELECT  * 
FROM    dbo.tbl_Main_Holding AS rm 
        LEFT JOIN dbo.tbl_Main_Holding_Requirements AS r
            ON r.MainHoldingID = rm.ID
        LEFT JOIN [dbo].[tbl_Features] AS f
            ON f.ID = r.FeatureID;
Run Code Online (Sandbox Code Playgroud)

如果需要将其备份到逗号分隔列表,则可以在表示层或SQL Server的XML Extensions中执行此操作:

SELECT  *,
        Features = STUFF(f.Features.value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM    dbo.tbl_Main_Holding AS rm 
        OUTER APPLY
        (   SELECT  CONCAT(',', f.Description)
            FROM    dbo.tbl_Main_Holding_Requirements AS r
                    INNER JOIN [dbo].[tbl_Features] AS f
                        ON f.ID = r.FeatureID
            WHERE   r.MainHoldingID = rm.ID
            FOR XML PATH(''), TYPE
        ) f (Features);
Run Code Online (Sandbox Code Playgroud)

如果第二步不可能,那么您可以使用LIKE以下方法解决此问题:

SELECT  * 
FROM    dbo.tbl_Main_Holding AS rm 
        LEFT JOIN [dbo].[tbl_Features] AS f
            ON ',' + rm.Requirements + ',' LIKE '%,' + CONVERT(VARCHAR(10), f.ID) + ',%';
Run Code Online (Sandbox Code Playgroud)

再一次,如果需要将功能简化为单行,那么您可以再次使用XML扩展:

SELECT  *,
        Features = STUFF(f.Features.value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM    dbo.tbl_Main_Holding AS rm 
        OUTER APPLY
        (   SELECT  CONCAT(',', f.Description)
            FROM    [dbo].[tbl_Features] AS f
            WHERE   ',' + rm.Requirements + ',' LIKE '%,' + CONVERT(VARCHAR(10), f.ID) + ',%'
            FOR XML PATH(''), TYPE
        ) f (Features);
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用某种Split函数将逗号分隔值拆分为列表,但正如本文中的测试所示,如果您不需要从列表中访问各个值,则使用它会更有效LIKE.