2016-09-23 38 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你是對的,我刪除了我無用的編輯! –