为什么使用此TSQL存储过程插入冗余记录?

时间:2016-01-15 22:43:12

标签: sql sql-server tsql group-by temp-tables

当我在LINQPad中运行这部分存储过程时:

create table #temp1
(
    MemberNo varchar(25),
    MemberItemCode varchar(25),
    ShortName varchar(25),
    ItemCode varchar(50),
    WVItem varchar(25),
    WVItemCode varchar(25),
    WVDescription varchar(250),
    Week1Usage varchar(25),
    Week1Price varchar(25)
)

INSERT INTO #temp1 (MemberNo, MemberItemCode, WVItemCode, WVDescription, Week1Usage, Week1Price) 
select MemberNo, ItemCode, WVItemCode, Description, SUM(QtyShipped), Price
FROM InvoiceDetail 
WHERE Unit=@Unit
AND INVOICEDATE BETWEEN @Begin AND @EndDate
GROUP BY Description, MemberNo, ItemCode, WVItemCode, Price

select * from #temp1 order by memberitemcode;

...我得到了我的希望,即每个MemberItemCode的一行数据,其列中的QtyShipped总和。

但是,当我使用“Week2”值填充相关表格,然后将它们组合起来时,如下所示:

CREATE Procedure [dbo].[priceVarianceTest]
    @Unit varchar(25),
    @BegDate datetime,
    @EndDate datetime 
AS 

DECLARE @Week1End datetime = DATEADD(Day, 6, @BegDate);
DECLARE @Week2Begin datetime = DATEADD(Day, 7, @BegDate);

. . .

create table #temp2
(
    MemberNo varchar(25),
    Week2Usage varchar(25),
    Week2Price varchar(25)
)

-- populate week2 vals
INSERT INTO #temp2 (MemberNo, Week2Usage, Week2Price)
select MemberNo, Sum(QtyShipped), Price
FROM InvoiceDetail 
WHERE Unit=@Unit
AND INVOICEDATE BETWEEN @Week2Begin AND @EndDate
GROUP BY Description, MemberNo, Price;

-- now I have some records with week1 vals, and some with week2 vals; combine them into a third table
create table #tempCombined
(
    MemberNo varchar(25),
    MemberItemCode varchar(25),
    ShortName varchar(25),
    ItemCode varchar(50),
    WVItem varchar(25),
    WVItemCode varchar(25),
    WVDescription varchar(250),
    Week1Usage varchar(25),
    Week2Usage varchar(25),
    UsageVariance varchar(25),
    Week1Price varchar(25),
    Week2Price varchar(25),
    PriceVariance varchar(25),
    PercentageOfPriceVariance varchar(25)
)

INSERT INTO #tempCombined (MemberNo, MemberItemCode, WVDescription, Week1Usage, Week1Price, week2Usage, week2Price)
select t1.MemberNo, t1.MemberItemCode, t1.WVDescription, t1.Week1Usage, t1.Week1Price, t2.Week2Usage, t2.Week2Price
FROM #temp1 as t1
JOIN #temp2 as t2 on t1.MemberNo = t2.MemberNo

...我得到的结果集已经走到了南方,我可以看到Kudzu在其中不断增长:我为每个MemberItemCode获得40毫安记录,而不是求和和分组工作。

当我对第二个临时表进行求和/分组时,为什么会出现这种情况,然后简单地将两个表合并为第三个表并返回?

更新

如果我将JOIN转换为LEFT JOIN,它解决了我正在哀悼的问题,但是Week2值(Week2Usage和Week2Price)变为静音/黑暗。

更新2

我希望Justin Cave的评论是问题的关键,但我将代码更改为:

-- populate week2 vals
INSERT INTO #temp2 (MemberNo, ItemCode, WVDescription, Week2Usage, Week2Price)
select MemberNo, ItemCode, Description, SUM(QtyShipped), Price
FROM InvoiceDetail 
WHERE Unit=@Unit
AND INVOICEDATE BETWEEN @Week2Begin AND @EndDate
GROUP BY MemberNo, ItemCode, Description, Price;

-- now I have some records with week1 vals, and some with week2 vals; combine them into a third table
create table #tempCombined
(
    MemberNo varchar(25),
    MemberItemCode varchar(25),
    ShortName varchar(25),
    ItemCode varchar(50),
    WVItem varchar(25),
    WVItemCode varchar(25),
    WVDescription varchar(250),
    Week1Usage varchar(25),
    Week2Usage varchar(25),
    UsageVariance varchar(25),
    Week1Price varchar(25),
    Week2Price varchar(25),
    PriceVariance varchar(25),
    PercentageOfPriceVariance varchar(25)
)

INSERT INTO #tempCombined (MemberNo, MemberItemCode, WVDescription, Week1Usage, Week1Price, week2Usage, week2Price)
select t1.MemberNo, t1.MemberItemCode, t1.WVDescription, t1.Week1Usage, t1.Week1Price, t2.Week2Usage, t2.Week2Price
FROM #temp1 as t1
LEFT JOIN #temp2 as t2 on t1.ItemCode = t2.ItemCode AND t1.MemberNo = t2.MemberNo and t1.WVDescription = t2.WVDescription

...但没有区别 - “Week2”值仍为NULL。

更新3

通过将连接类型更改为FULL OUTER JOIN,我现在获得数百条记录,其中第1周的值为val,没有第2周的值,数百条记录包含第2周的值且没有第1周的值,但没有一个记录包含两周的值

#tempCombined的计数是#temp1和#temp2组合的计数(IOW,它们被堆在一起,而不是合并)。

更新4

直到星期一我才能测试它,但我想也许这样可行:

INSERT INTO TEMP1 (MEMBERITEMCODE, WEEK1USAGE, WEEK1PRICE)
SELECT MEMBERITEMCODE, SUM(QTYSHIPPED), PRICE FROM INVOICEDETAIL 
WHERE UNIT=@UNIT AND INVOICEDATE BETWEEN @BEGDATE AND @WEEK1END
GROUP BY MEMBERITEMCODE, PRICE

INSERT INTO TEMP2 (MEMBERITEMCODE, WEEK2USAGE, WEEK2PRICE)
SELECT MEMBERITEMCODE, SUM(QTYSHIPPED), PRICE FROM INVOICEDETAIL 
WHERE UNIT=@UNIT AND INVOICEDATE BETWEEN @WEEK2BEGIN AND @ENDDATE
GROUP BY MEMBERITEMCODE, PRICE

INSERT INTO TEMP3 (MEMBERITEMCODE, WEEK1USAGE, WEEK1PRICE, WEEK2USAGE, WEEK2PRICE)
SELECT T1.MEMBERITEMCODE, T1.WEEK1USAGE, T1.WEEK1PRICE, T2.WEEK2USAGE, T2.WEEK2PRICE
FROM TEMP1 T1
LEFT JOIN TEMP2 T2 ON T1.MEMBERITEMCODE = T2.MEMBERITEMCODE

0 个答案:

没有答案