【问题标题】:How to join comma separated column values with another table as rows如何将逗号分隔的列值与另一个表连接为行
【发布时间】:2019-06-01 14:55:52
【问题描述】:

我正在尝试通过首先转换我正在成功执行的“SupplierId”列中的逗号分隔值来连接两个表。 但是,当我尝试通过外键“DCLink”使用供应商名称加入另一个表“供应商”时,问题就出现了。

这就是我的意思:

原始表的选择语句,

  SELECT  InquiryId, SupplierId FROM Procure_InquiryDetails

给出这个结果

InquiryId   SupplierId

1           2,3
2           175
3           170,280
5           
7           12
8           5,9

我可以使用这个 sql 语句从 SupplierId 中拆分列

;WITH CTE
    AS
    (
        SELECT  InquiryId,
                [xml_val] = CAST('<t>' + REPLACE(SupplierId,',','</t><t>') + '</t>' AS XML)
        FROM Procure_InquiryDetails
    )

SELECT  InquiryId,
        [SupplierId] = col.value('.','VARCHAR(100)')
FROM CTE
CROSS APPLY [xml_val].nodes('/t') CA(col) 

并得到这些结果

InquiryId   SupplierId
    1           2
    1           3
    2           175
    3           170
    3           280
    5   
    7           12
    8           5
    8           9 

当我应用这段代码将 InquiryDetails 表连接到供应商名称上的供应商表时,

;WITH CTE
AS
(
    SELECT  InquiryId,
            [xml_val] = CAST('<t>' + REPLACE(SupplierId,',','</t><t>') + '</t>' AS XML),
            Vendor.Name
    FROM Procure_InquiryDetails inner join Vendor
    on ',' + Procure_InquiryDetails.SupplierId + ',' like '%,' + cast(Vendor.DCLink as nvarchar(20)) + ',%'
)

SELECT  InquiryId, Name,
        [SupplierId] = col.value('.','VARCHAR(100)')
FROM CTE
CROSS APPLY [xml_val].nodes('/t') CA(col)

它给了我这个非常不方便的结果:

InquiryId   Name                                                                                                                                                   SupplierId
----------- ------------------------------------------------------------------------------------------------------------------------------------------------------ ----------------------------------------------------------------------------------------------------
1           Accesskenya Group Ltd                                                                                                                                  2
1           Accesskenya Group Ltd                                                                                                                                  3
1           Aquisana Ltd                                                                                                                                           2
1           Aquisana Ltd                                                                                                                                           3
2           TOYOTA KENYA                                                                                                                                           175
3           Institute of Chartered Shipbrokers ICS-USD                                                                                                             170
3           Institute of Chartered Shipbrokers ICS-USD                                                                                                             280
7           CMA CGM Kenya Ltd                                                                                                                                      12
8           Aon Kenya Insurance Brokers Ltd                                                                                                                        5
8           Aon Kenya Insurance Brokers Ltd                                                                                                                        9
8           Bill investments ltd                                                                                                                                   5
8           Bill investments ltd

我希望 join 语句能像原来的 select 语句一样显示和流动。

我被卡住了,我似乎无法弄清楚我哪里出错了。 有正确方向的指针吗?

【问题讨论】:

  • Sql server 哪个版本?
  • Sql Server 2014
  • 为什么还要在列中存储逗号分隔值?相反,您应该构建一个适当的规范化关系数据模型,这样一开始就不会发生此类问题。
  • 它是一个继承的数据库。如果我按照自己的方式行事,我不会使用它,但值班电话
  • @Chesaro 您可以查看以下链接,了解可在 sql server 2014 中使用的许多字符串拆分用户功能:stackoverflow.com/questions/10914576/t-sql-split-string

标签: c# sql sql-server tsql sql-server-2014


【解决方案1】:

您忘记提供预期的结果,所以这是在黑暗中刺伤,但是,拆分字符串并将结果与​​ JOIN 一起使用有什么问题:

SELECT {Needed Columns}
FROM dbo.Procure_InquiryDetails PID
     CROSS APPLY STRING_SPLIT(PID.SupplierId,',') SS
     JOIN dbo.Vendor V ON SS.[value] = V.SupplierID;

但是,理想情况下,您不应该在 RDBMS 中存储分隔数据。考虑切换到适当的规范化多对多关系结构。

如果您仍在使用 SQL Server 2008(我强烈建议您升级到该版本),那么您可以使用 delimitedsplit8k,或者在 2012/2014 上,您可以使用 delimitedsplit8k_lead

【讨论】:

  • 您的回答非常清楚,非常感谢,但是我想知道您上面提供的代码如何在我的 sql server 2014 上实现 delimitedsplit8k_lead 而无需函数声明。这是因为我在 c# 应用程序上使用 sql 字符串
  • 您需要先在相关数据库中创建函数并调用它。另外,我相信这两个函数都返回列item(和itemnumber)而不是[value]
  • @Larnu 我在检查了您提到的delimitedsplit8k 函数后删除了我的答案。我完全同意你的看法,最好使用它。 +1
【解决方案2】:

假设您使用的是 SQL Server 2016,您可以使用 string_split() 解析出您的 CSV 列(此外:字段中的逗号分隔值表示数据模型不佳),而无需使用 CTE 或 XML方法。

select I.inquiry_id, sup.value,V.Name
from Procure_InquiryDetails I
CROSS APPLY string_split(I.supplier_value,',') sup
join Vendor v on v.DCLink = sup.value

【讨论】:

  • sql server 2014 怎么样?
  • 然后您可以将string_split() 替换为您可以在互联网上找到的任何其他字符串拆分函数。
  • alroc,我应该早点说。太感谢了。我结合了您的答案并使用@Hadi 链接上的功能对其进行了修改,瞧!
猜你喜欢
  • 2010-11-06
  • 1970-01-01
  • 2011-11-27
  • 1970-01-01
  • 2020-04-13
  • 1970-01-01
  • 2016-07-10
  • 1970-01-01
相关资源
最近更新 更多