2016-09-23 12 views
3

我有两个表:
1.索引和索引数量
2.索引和具有指定的boxcodes索引的数量。 Boxcode是一些框,其中包含索引。
如何连接表,连接一些数据

1. input table 1 

item_id quantity 
1  10 
2  15 
3  5 
1  5 
1  5 
2  5 
3  5 

sum: 
1 - 20 
2 - 20 
3 - 10 



2. input table 2 

item_id quantity boxcode 
1  3   abc 
2  2   abc 
1  8   def 
3  10   ghi 
1  9   ghi 
2  9   def 
2  8   ghi    !!!!!!! 

1 item_id once on 1 boxcode 

我希望得到的结果:

从表1
3. result 

    item_id quantity boxcodes 
    1  10   abc/3, def/7 
    2  15   abc/2, def/9, ghi/4 
    3  5   ghi/5 
    1  5   def/1, ghi/4 
    1  5   ghi/5 
    2  5   ghi/4      !!!!!!!! 
    3  5   ghi/5 

记录必须以相同的顺序。
我不知道它是如何做到的。
有什么建议吗?

CREATE TABLE #input1 
(
    rownum int, 
    item_id int, 
    quantity int 
) 

CREATE TABLE #input2 
(
    item_id int, 
    quantity int, 
    boxcode varchar(10) 
) 

INSERT INTO #input1 VALUES (1,1,10) 
INSERT INTO #input1 VALUES (2,2,15) 
INSERT INTO #input1 VALUES (3,3,5) 
INSERT INTO #input1 VALUES (4,1,5) 
INSERT INTO #input1 VALUES (5,1,5) 
INSERT INTO #input1 VALUES (6,2,5) 
INSERT INTO #input1 VALUES (7,3,5) 

INSERT INTO #input2 VALUES (1,3, 'abc') 
INSERT INTO #input2 VALUES (2,2, 'abc') 
INSERT INTO #input2 VALUES (1,8, 'def') 
INSERT INTO #input2 VALUES (3,10, 'ghi') 
INSERT INTO #input2 VALUES (1,9, 'ghi') 
INSERT INTO #input2 VALUES (2,9, 'def') 
INSERT INTO #input2 VALUES (2,8, 'ghi') 

select * from #input1 
select * from #input2 

drop table #input1 
drop table #input2 

result

感谢,

+0

你不必表名或任何所以它很难写答案,但尝试到U SE ROW_NUMBER()OVER(ORDER BY ITEM_ID)上的第一张表 –

+0

如何获得abc/3..def/7 – TheGameiswar

+0

表1中的记录必须是相同的顺序。 我从input_table_1获取第一条记录,并使用item_id1(input_table_2)查找boxcodes。我需要数量:10.我从'abc'框中获得3个,'def'框中获得7个。 3 + 7 = 10 – peter

回答

2

怪异,但它的工作原理:

;WITH rec1 AS (
    SELECT rownum, 
      item_id, 
      1 as q, 
      1 as [Level], 
      quantity 
    from #input1 
    UNION ALL 
    SELECT r.rownum, 
      r.item_id, 
      1, 
      [Level] + 1, 
      i.quantity 
    FROM rec1 r 
    INNER JOIN #input1 i 
     ON r.rownum = i.rownum AND r.item_id = i.item_id 
    WHERE [Level] < i.quantity 
), rec2 AS (
    SELECT boxcode, 
      item_id, 
      1 as q, 
      1 as [Level], 
      quantity 
    from #input2 
    UNION ALL 
    SELECT r.boxcode, 
      r.item_id, 
      1, 
      [Level] + 1, 
      i.quantity 
    FROM rec2 r 
    INNER JOIN #input2 i 
     ON r.boxcode = i.boxcode AND r.item_id = i.item_id 
    WHERE [Level] < i.quantity 
), cte1 AS (
    SELECT *, 
      ROW_NUMBER() OVER (PARTITION BY item_id ORDER BY item_id, rownum) as rn 
    FROM rec1 
), cte2 AS (
    SELECT *, 
      ROW_NUMBER() OVER (PARTITION BY item_id ORDER BY item_id, boxcode) as rn 
    FROM rec2 
), final AS (
    SELECT c1.rownum, 
      c1.item_id, 
      c1.quantity, 
      c2.boxcode+'/'+CAST(SUM(c2.q) as nvarchar(10)) as boxcodes 
    FROM cte1 c1 
    INNER JOIN cte2 c2 
     ON c1.item_id = c2.item_id and c1.rn = c2.rn 
    GROUP BY c1.rownum, c1.item_id, c1.quantity, c2.boxcode 
) 

SELECT DISTINCT 
       f.rownum, 
       f.item_id, 
       f.quantity, 
       STUFF((
        SELECT ', '+f1.boxcodes 
        FROM final f1 
        WHERE f1.rownum = f.rownum 
         AND f1.item_id = f.item_id 
         AND f1.quantity = f.quantity 
        FOR XML PATH('') 
       ),1,2,'') boxcodes 
FROM final f 

输出的数据集您提供:

rownum item_id quantity boxcodes 
1  1  10   abc/3, def/7 
2  2  15   abc/2, def/9, ghi/4 
3  3  5   ghi/5 
4  1  5   def/1, ghi/4 
5  1  5   ghi/5 
6  2  5   ghi/4 
7  3  5   ghi/5 

主要想法是在两个表格中传播数量为小零件1。比添加行号,然后加入并获得结果。

1

一个解决方案(但它完全基于gofr1的答案,说实话!),简化一下,将创建一个数字表,其中包含尽可能多的数字,只要你想。

CREATE TABLE Numbers(Number INT PRIMARY KEY); 

INSERT Numbers 
SELECT TOP 1000 ROW_NUMBER() OVER (ORDER BY name) 
FROM sys.all_columns; 

这将避免2递归CTE。

然后,您可以使用相同的逻辑gofr1:

with rec1 AS (
    SELECT 
      ROW_NUMBER() OVER (PARTITION BY item_id ORDER BY item_id, rownum) as rn, 
      rownum, 
      item_id, 
      case when quantity = 0 then 0 else 1 end as q, 
      quantity 
    from #input1 
    join Numbers n on n.Number <= quantity 
) 

, rec2 AS (
    SELECT 
    ROW_NUMBER() OVER (PARTITION BY item_id ORDER BY item_id, boxcode) as rn, 
      boxcode, 
      item_id, 
      case when quantity = 0 then 0 else 1 end as q, 
      quantity 
    from #input2 
    join Numbers n on n.Number <= quantity 
), 

final AS (
    SELECT c1.rownum, 
      c1.item_id, 
      c1.quantity, 
      c2.boxcode+'/'+CAST(SUM(c2.q) as nvarchar(10)) as boxcodes 
    FROM rec1 c1 
    INNER JOIN rec2 c2 
     ON c1.item_id = c2.item_id and c1.rn = c2.rn 
    GROUP BY c1.rownum, c1.item_id, c1.quantity, c2.boxcode 
), 
stuffed as (
SELECT 
     distinct rownum,  
     f.item_id, 
     f.quantity, 
     STUFF((
      SELECT ', '+f1.boxcodes 
      FROM final f1 
      WHERE f1.rownum = f.rownum 
       AND f1.item_id = f.item_id 
       AND f1.quantity = f.quantity 
      FOR XML PATH('') 
     ),1,2,'') boxcodes 
FROM final f 
group by item_id, quantity, boxcodes, rownum) 

select * 
from stuffed 
order by rownum 
+0

感谢您编辑我的答案!请注意:OP在他的问题中添加了rownum,请参阅创建脚本的一部分。 – gofr1

+0

@ gofr1你是对的,我删除了我无用的编辑! –