SQL如何根据目标源

时间:2016-10-18 08:39:07

标签: sql sql-server-2014 common-table-expression

我有两个表,我想加入并显示数量与详细信息。 表与ITM,DIA联系,ITM / DIA组合表中的总数量相等

我想在table1上拆分table2数量,并将table2数据与table1数据一起填充。

我有以下数据供您参考,“table1”和“table2”。你可以在表“tableResult”

中看到我的预期结果
CREATE TABLE table1
    (`ITM` varchar(5), `DIA` varchar(4), `LOC` varchar(4), `ID` varchar(3), `QTY` int)
;

INSERT INTO table1
    (`ITM`, `DIA`, `LOC`, `ID`, `QTY`)
VALUES
    ('Item1', 'DIA1', 'LOC1', 'ID1', 3),
    ('Item1', 'DIA1', 'LOC2', 'ID2', 4),
    ('Item1', 'DIA1', 'LOC2', 'ID2', 6),
    ('Item1', 'DIA2', 'LOC2', 'ID2', 6),
    ('Item1', 'DIA2', 'LOC3', 'ID3', 18),
    ('Item1', 'DIA2', 'LOC4', 'ID4', 90),
    ('Item1', 'DIA2', 'LOC4', 'ID5', 23),
    ('Item1', 'DIA3', 'LOC5', 'ID6', 50),
    ('Item1', 'DIA3', 'LOC6', 'ID7', 20),
    ('Item2', 'DIA1', 'LOC4', 'ID8', 44),
    ('Item2', 'DIA2', 'LOC5', 'ID8', 21),
    ('Item2', 'DIA3', 'LOC6', 'ID9', 20)
;


CREATE TABLE table2
    (`ITM` varchar(5), `DIA` varchar(4), `NTA` varchar(5), `QTY` int)
;

INSERT INTO table2
    (`ITM`, `DIA`, `NTA`, `QTY`)
VALUES
    ('Item1', 'DIA1', 'NTA1', 10),
    ('Item1', 'DIA1', 'NTA2', 3),
    ('Item1', 'DIA2', 'NTA3', 30),
    ('Item1', 'DIA2', 'NTA4', 7),
    ('Item1', 'DIA2', 'NTA5', 100),
    ('Item1', 'DIA3', 'NTA6', 70),
    ('Item2', 'DIA1', 'NTA7', 22),
    ('Item2', 'DIA1', 'NTA8', 20),
    ('Item2', 'DIA2', 'NTA9', 6),
    ('Item2', 'DIA2', 'NTA10', 15),
    ('Item2', 'DIA3', 'NTA11', 8),
    ('Item2', 'DIA3', 'NTA11', 12)
;


CREATE TABLE tableResult
    (`ITM` varchar(5), `DIA` varchar(4), `LOC` varchar(4), `ID` varchar(3), `QTY` int, `NTA` varchar(5), `NewQTY` int)
;

INSERT INTO tableResult
    (`ITM`, `DIA`, `LOC`, `ID`, `QTY`, `NTA`, `NewQTY`)
VALUES
    ('Item1', 'DIA1', 'LOC1', 'ID1', 3, 'NTA1', 3),
    ('Item1', 'DIA1', 'LOC2', 'ID2', 4, 'NTA1', 4),
    ('Item1', 'DIA1', 'LOC2', 'ID2', 6, 'NTA1', 3),
    ('Item1', 'DIA1', 'LOC2', 'ID2', 6, 'NTA2', 3),
    ('Item1', 'DIA2', 'LOC2', 'ID2', 6, 'NTA3', 6),
    ('Item1', 'DIA2', 'LOC3', 'ID3', 18, 'NTA3', 18),
    ('Item1', 'DIA2', 'LOC4', 'ID4', 90, 'NTA3', 6),
    ('Item1', 'DIA2', 'LOC4', 'ID4', 90, 'NTA4', 7),
    ('Item1', 'DIA2', 'LOC4', 'ID4', 90, 'NTA5', 77),
    ('Item1', 'DIA2', 'LOC4', 'ID5', 23, 'NTA5', 23),
    ('Item1', 'DIA3', 'LOC5', 'ID6', 50, 'NTA6', 50),
    ('Item1', 'DIA3', 'LOC6', 'ID7', 20, 'NTA6', 20),
    ('Item2', 'DIA1', 'LOC4', 'ID8', 44, 'NTA7', 22),
    ('Item2', 'DIA1', 'LOC4', 'ID8', 44, 'NTA8', 20),
    ('Item2', 'DIA2', 'LOC5', 'ID8', 21, 'NTA9', 6),
    ('Item2', 'DIA2', 'LOC5', 'ID8', 21, 'NTA10', 15),
    ('Item2', 'DIA3', 'LOC6', 'ID9', 20, 'NTA11', 8),
    ('Item2', 'DIA3', 'LOC6', 'ID9', 20, 'NTA11', 12)
;

以下是数据截图; enter image description here

我可以用proc和跟随光标来实现它,但是我想在SQL 2014中有任何简单的方法,我知道CTE重用技巧会有所帮助..

请您分享一下您的解决方案吗?非常感谢您的宝贵意见..

1 个答案:

答案 0 :(得分:1)

你只需要以table1和table2为单位爆炸数量,然后将它们并排连接 注意FN_NUMBERS(n),它是一个函数只返回一个数字从1到n的列,你需要它在你的数据库中,有很多方法可以做到这一点,只需google for" tally tables&#34 ;或look here 我使用以下内容:

CREATE FUNCTION FN_NUMBERS(
     @MAX INT
)
RETURNS @N TABLE (N INT NOT NULL PRIMARY KEY)  
BEGIN
     WITH
       Pass0 as (select '1' as C union all select '1'),       --2 rows
       Pass1 as (select '1' as C from Pass0 as A, Pass0 as B),--4 rows
       Pass2 as (select '1' as C from Pass1 as A, Pass1 as B),--16 rows
       Pass3 as (select '1' as C from Pass2 as A, Pass2 as B),--256 rows
       Pass4 as (select TOP (@MAX) '1' as C from Pass3 as A, Pass3 as B)    --65536 rows
       ,Tally as (select TOP (@MAX) '1' as C from Pass4 as A, Pass2 as B, Pass1 as C)  --4194304 rows
       --,Tally as (select TOP (@MAX) '1' as C from Pass4 as A, Pass3 as B)               --16777216 rows
       --,Tally as (select TOP (@MAX) '1' as C from Pass4 as A, Pass4 as B)               --4294836225 rows
     INSERT INTO @N
     SELECT TOP (@MAX) ROW_NUMBER() OVER(ORDER BY C) AS N
     FROM Tally
     RETURN
END

回到sql ..

;with
t1 as (
    select *, ROW_NUMBER() over (partition by itm,dia order by loc,id) rn      
    from table1 t1
    join FN_NUMBERS(500) on n<=t1.qty
),
t2 as (
    select *, ROW_NUMBER() over (partition by itm,dia order by nta) rn      
    from table2 t2
    join FN_NUMBERS(500) on n<=t2.qty
),
t3 as (
    select t1.itm, t1.dia, t1.loc, t1.id, t1.qty, t2.nta, count(t1.n) NewQTY
    from  t1
    join  t2 on t1.itm=t2.itm and t1.dia = t2.dia and t1.rn=t2.rn
    group by t1.itm, t1.dia, t1.loc, t1.id, t1.qty, t2.nta
)
select * 
from t3
order by 1,2,3,4,5,6