使用一个创建两个表

时间:2019-02-08 03:37:39

标签: sql sql-server database

CREATE TABLE ItemsOfStores ( Item int, Store int );

对于上面的示例,该数据将包含:

INSERT INTO ItemsOfStores (Item,Store)
    VALUES (1,1),(1,3),(4,1),(4,3),(5,1),(5,3),(2,1),
           (2,2),(2,4),(3,1),(3,2),(3,4);

我需要SQL将结果插入2个表中:

CREATE TABLE StoreGroups ( GroupId int, Store int )
CREATE TABLE ItemsOfGroups ( GroupId int, Item int )

在上面的示例中,项目1、4和5位于商店1和3,那么会有一组 由商店1和3组成的商店,我将其称为组1。因此,组1拥有商店1和3,因此会将(1,1),(1,3)放入StoreGroups, 并且项目1、4和5在该组中,因此(1,1),(1,4),(1,5)将进入ItemsOfGroups。

在我的示例中,项目2和3分别位于商店1、2和4,那么会有第二组 由商店1、2和4组成的商店,我将其称为组2。因此(2,1),(2,2),(2,4)将进入StoreGroups,而(2,2),( 2,3)将进入ItemsOfGroups。

因此,这个小例子的最终结果将填充StoreGroups 与(1,1),(1,3),(2,1),(2,2),(2,4), 和具有(1,1),(1,4),(1,5),(2,2),(2,3)的ItemsOf

enter image description here

1 个答案:

答案 0 :(得分:2)

我想你想要这样的东西。

    CREATE TABLE ItemsOfStores ( Item int, Store int );


    INSERT INTO ItemsOfStores (Item,Store)
        VALUES (1,1),(1,3),(4,1),(4,3),(5,1),(5,3),(2,1),
               (2,2),(2,4),(3,1),(3,2),(3,4);


    CREATE TABLE StoreGroups ( GroupId int, Store int );
    CREATE TABLE ItemsOfGroups ( GroupId int, Item int );

    Insert into StoreGroups

    SELECT z.GroupID,  value 
    FROM (
            Select    ROW_NUMBER() OVER(ORDER BY x.Store ASC)as GroupID, x.Store , x.Item
            from 
                ( 
                    select 

                    T3.Store, 

                    stuff((SELECT  ', ' + cast(Item as varchar(10))
                            FROM (
                                    select Item, 
                                        stuff((SELECT  ', ' + cast(Store as varchar(10))
                                                FROM ItemsOfStores t2
                                                where t2.Item = t1.Item
                                                order by Store
                                                FOR XML PATH('')),1,1,'') as Store
                                    from ItemsOfStores t1
                                    group by Item
                                )t4
                            where t4.Store = t3.Store
                            order by Item
                            FOR XML PATH('')),1,1,'') 
                    as Item

                    from (
                                            select Item, 
                                              stuff((SELECT  ', ' + cast(Store as varchar(10))
                                                       FROM ItemsOfStores t2
                                                       where t2.Item = t1.Item
                                                       order by Store
                                                       FOR XML PATH('')),1,1,'') as Store
                                            from ItemsOfStores t1
                                            group by Item


                                    ) t3
                    group by T3.Store
                )  x
        )z
    CROSS APPLY STRING_SPLIT(z.Store, ',');

    Select * from StoreGroups

返回:

    GroupId Store
    1       1
    1       2
    1       4
    2       1
    2       3

相同的逻辑:

    Insert into ItemsOfGroups
    -- Use String Split (SQL2016+) function to split merged colums back into seperate values with their related GroupID
    SELECT z.GroupID,  value 
    FROM (-- Add GroupID which is related to both merged Item rows and merged store rows
            Select    ROW_NUMBER() OVER(ORDER BY x.Store ASC)as GroupID, x.Store , x.Item
            from 
                ( -- Merge Item values into one row (grouped by Grouped result of Store)
                    select Store, 
                      stuff((SELECT  ', ' + cast(Item as varchar(10))
                               FROM (
                                        select Item, 
                                          stuff((SELECT  ', ' + cast(Store as varchar(10))
                                                   FROM ItemsOfStores t2
                                                   where t2.Item = t1.Item
                                                   order by Store
                                                   FOR XML PATH('')),1,1,'') as Store
                                        from ItemsOfStores t1
                                        group by Item
                                    )t4
                               where t4.Store = t3.Store
                               order by Item
                               FOR XML PATH('')),1,1,'') as Item
                    from ( -- Merge Store values into one row (grouped by Item)
                                select Item, 
                                  stuff((SELECT  ', ' + cast(Store as varchar(10))
                                           FROM ItemsOfStores t2
                                           where t2.Item = t1.Item
                                           order by Store
                                           FOR XML PATH('')),1,1,'') as Store
                                from ItemsOfStores t1
                                group by Item


                        ) t3
                    group by T3.Store
                )  x
            )z
        CROSS APPLY STRING_SPLIT(z.Item, ',');

    Select * from ItemsOfGroups

返回:

    GroupId Item
    1       2
    1       3
    2       1
    2       4
    2       5