我知道LEFT OUTER JOIN的意思是“给我左表中的所有内容,并返回右表中匹配项的详细信息,以及没有匹配项的NULL值”,因此给出以下代码:
CREATE TABLE #Items(
WarehouseNumber varchar(2),
ItemNumber varchar(8),
ItemDescription varchar(50)
)
INSERT INTO #Items(WarehouseNumber, ItemNumber, ItemDescription) VALUES('01', '12345', 'Widget')
INSERT INTO #Items(WarehouseNumber, ItemNumber, ItemDescription) VALUES('02', '12345', 'Widget')
INSERT INTO #Items(WarehouseNumber, ItemNumber, ItemDescription) VALUES('07', '12345', 'Widget')
CREATE TABLE #InvoiceHdr(
InvoiceNumber varchar(8),
WarehouseNumber varchar(2),
DateOrdered datetime,
DateInvoiced datetime
)
INSERT INTO #InvoiceHdr(InvoiceNumber, WarehouseNumber, DateOrdered, DateInvoiced) VALUES('1', '01', '20190101', '20190102')
INSERT INTO #InvoiceHdr(InvoiceNumber, WarehouseNumber, DateOrdered, DateInvoiced) VALUES('2', '07', '20190102', '20190103')
INSERT INTO #InvoiceHdr(InvoiceNumber, WarehouseNumber, DateOrdered, DateInvoiced) VALUES('3', '02', '20190201', '20190202')
INSERT INTO #InvoiceHdr(InvoiceNumber, WarehouseNumber, DateOrdered, DateInvoiced) VALUES('4', '07', '20190216', '20190217')
INSERT INTO #InvoiceHdr(InvoiceNumber, WarehouseNumber, DateOrdered, DateInvoiced) VALUES('5', '07', '20190221', '20190222')
CREATE TABLE #InvoiceDtl(
InvoiceNumber varchar(8),
InvoiceLineItem int,
ItemNumber varchar(8),
QtyOrdered int,
QtyShipped int
)
INSERT INTO #InvoiceDtl(InvoiceNumber, InvoiceLineItem, ItemNumber, QtyOrdered, QtyShipped) VALUES('1', 1, '12345', 4, 4)
INSERT INTO #InvoiceDtl(InvoiceNumber, InvoiceLineItem, ItemNumber, QtyOrdered, QtyShipped) VALUES('2', 1, '12345', 33, 30)
INSERT INTO #InvoiceDtl(InvoiceNumber, InvoiceLineItem, ItemNumber, QtyOrdered, QtyShipped) VALUES('3', 1, '12345', 5, 5)
INSERT INTO #InvoiceDtl(InvoiceNumber, InvoiceLineItem, ItemNumber, QtyOrdered, QtyShipped) VALUES('4', 1, '12345', 7, 7)
INSERT INTO #InvoiceDtl(InvoiceNumber, InvoiceLineItem, ItemNumber, QtyOrdered, QtyShipped) VALUES('5', 1, '12345', 8, 8
SELECT I.ItemNumber,
I.WarehouseNumber,
SUM(Details.Qty) 'Qty'
FROM #Items I
LEFT OUTER JOIN (SELECT IH.DateInvoiced,
IH.WarehouseNumber,
ID.ItemNumber,
SUM(ID.QtyOrdered) 'Qty'
FROM #InvoiceHdr IH
INNER JOIN #InvoiceDtl ID ON IH.InvoiceNumber = ID.InvoiceNumber
GROUP BY IH.DateInvoiced,
ID.ItemNumber,
IH.WarehouseNumber) Details ON I.ItemNumber = Details.ItemNumber
AND I.WarehouseNumber = Details.WarehouseNumber
WHERE Details.DateInvoiced >= '20190101'
AND Details.DateInvoiced < '20190108'
GROUP BY I.ItemNumber,
I.WarehouseNumber
...我收到以下结果:
ItemNumber | WarehouseNumber | Qty
==================================
12345 | 01 | 4
12345 | 07 | 33
当我期望的时候:
ItemNumber | WarehouseNumber | Qty
==================================
12345 | 01 | 4
12345 | 02 | NULL
12345 | 07 | 33
我看过this question and solution,但是公认的解决方案特别指出“我知道这在SQL Server中不起作用,但对MySQL有效”。我想让它们在SQL Server中运行(如果可能,请在2005年运行,如果不能,请在2016年运行)
答案 0 :(得分:1)
将WHERE
更改为AND
,您应该会很好。将日期条件放在WHERE
子句中会将其从结果集中排除。将其放入联接中会将其从联接表中排除,从而导致结果集中为NULL值。
SELECT I.ItemNumber
, I.WarehouseNumber
, SUM(Details.Qty) 'Qty'
FROM #Items I
LEFT OUTER JOIN
(
SELECT IH.DateInvoiced
, IH.WarehouseNumber
, ID.ItemNumber
, SUM(ID.QtyOrdered) 'Qty'
FROM #InvoiceHdr IH
INNER JOIN #InvoiceDtl ID ON IH.InvoiceNumber = ID.InvoiceNumber
GROUP BY IH.DateInvoiced, ID.ItemNumber, IH.WarehouseNumber
) Details ON
I.ItemNumber = Details.ItemNumber
AND I.WarehouseNumber = Details.WarehouseNumber
/*WHERE*/ AND Details.DateInvoiced >= '20190101'
AND Details.DateInvoiced < '20190108'
GROUP BY I.ItemNumber, I.WarehouseNumber