Inner join based on comma separated field

后端 未结 1 1520
天涯浪人
天涯浪人 2021-01-14 23:56

I have two tables InvoiceLocations and PCInvoiceLocation with respective data.

i just want a output like following.

1条回答
  •  北海茫月
    2021-01-15 00:42

    Create Testing Environment

    First i used the following command to create the testing environment

    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)
    

    Solution

    You can achieve this in 3 steps:

    1. First split the Locations field into rows
    2. Join these rows with the InvoiceLocations table to get related values
    3. Aggregate the results into on comma seperated filed

    First split the Locations field into rows

    ;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 > '')
    

    Join these rows with the InvoiceLocations table to get related values

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

    Aggregate the results into on comma seperated filed

    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
    

    The Whole Query will looks like

    ;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
    

    Result:

    SQLFiddle Demo

    References

    • SQL Server : GROUP BY clause to get comma-separated values
    • Turning a Comma Separated string into individual rows

    0 讨论(0)
提交回复
热议问题