基于逗号分隔字段的内连接

时间:2017-11-23 19:30:54

标签: sql sql-server sql-server-2008 tsql join

我有两个表格InvoiceLocationsPCInvoiceLocation以及各自的数据。

enter image description here

我只想要输出如下。

enter image description here

请帮忙。

评论代码:

declare @@LocationId nvarchar(50)='1,2' 
declare @@sql nvarchar(Max) 
Declare @@Output table(Code nvarchar(10) not null) 
Set @@sql='SELECT Code FROM invoiceLocations WHERE Id IN ('+@LocationId+')' 
insert @@Output(Code) 
exec sp_executesql @sql

1 个答案:

答案 0 :(得分:2)

创建测试环境

首先,我使用以下命令创建测试环境

CREATE TABLE InvoiceLocations (ID int,CODE varchar(3), VALUE varchar(3));
CREATE TABLE PCInvoiceLOcation (ID int,CategoryID INT, Locations varchar(50),DefaultLocationID int);


INSERT INTO InvoiceLocations(ID,CODE,VALUE)
VALUES(1,'BFC','BFC'),
(2,'BRH','BRH'),
(3,'BRP','BRP'),
(4,'BCC','BCC')

INSERT INTO PCInvoiceLOcation(ID,CategoryID,Locations,DefaultLocationID)
VALUES(1,1,'1,2',1),
(2,2,'2,3',2),
(3,3,'2,1',1),
(4,4,'4',4)

解决方案

您可以通过3个步骤实现此目的:

  1. 首先将Locations字段拆分为行
  2. 使用InvoiceLocations表加入这些行以获取相关值
  3. 将结果汇总到逗号分隔的字段
  4. 首先将Locations字段拆分为行

    ;with tmp(ID,CategoryID,Locations,DefaultLocationID,  DataItem , Data) as (
            select ID,CategoryID,Locations,DefaultLocationID, 
                    CAST( LEFT(Locations, CHARINDEX(',',Locations+',')-1) as varchar(5)),
                    STUFF(Locations, 1, CHARINDEX(',',Locations+','), '')
            from PCInvoiceLOcation
        union all
            select ID,CategoryID,Locations,DefaultLocationID,  
                    CAST(LEFT(Data, CHARINDEX(',',Data+',')-1) AS Varchar(5)),
                    STUFF(Data, 1, CHARINDEX(',',Data+','), '')
            from tmp
            where Data > '')
    

    使用InvoiceLocations表加入这些行以获取相关值

    select tmp.ID,CategoryID,Locations,DefaultLocationID,  DataItem , InvoiceLocations.VALUE
    from tmp
    INNER JOIN InvoiceLocations ON tmp.DataItem = InvoiceLocations.ID
    

    将结果汇总到逗号分隔字段

    Select ID,CategoryID,Locations,DefaultLocationID,  
                STUFF((SELECT ', ' + VALUE
                           FROM Tmp2 AS T3 
                           WHERE T3.ID = tmp2.ID 
                          FOR XML PATH('')), 1, 2, '')
        FROM tmp2 
        GROUP BY ID,CategoryID,Locations,DefaultLocationID
    

    整个查询将类似于

    ;with tmp(ID,CategoryID,Locations,DefaultLocationID,  DataItem , Data) as (
            select ID,CategoryID,Locations,DefaultLocationID, 
                    CAST( LEFT(Locations, CHARINDEX(',',Locations+',')-1) as varchar(5)),
                    STUFF(Locations, 1, CHARINDEX(',',Locations+','), '')
            from PCInvoiceLOcation
        union all
            select ID,CategoryID,Locations,DefaultLocationID,  
                    CAST(LEFT(Data, CHARINDEX(',',Data+',')-1) AS Varchar(5)),
                    STUFF(Data, 1, CHARINDEX(',',Data+','), '')
            from tmp
            where Data > '')
        ,tmp2(ID,CategoryID,Locations,DefaultLocationID,  DataItem , VALUE) AS (
            select tmp.ID,CategoryID,Locations,DefaultLocationID,  DataItem , InvoiceLocations.VALUE
            from tmp
            INNER JOIN InvoiceLocations ON tmp.DataItem = InvoiceLocations.ID) 
    
            Select ID,CategoryID,Locations,DefaultLocationID,  
                    STUFF((SELECT ', ' + VALUE
                               FROM Tmp2 AS T3 
                               WHERE T3.ID = tmp2.ID 
                              FOR XML PATH('')), 1, 2, '')
            FROM tmp2 
            GROUP BY ID,CategoryID,Locations,DefaultLocationID
    

    结果:

    enter image description here

    SQLFiddle Demo

    <强>参考