我正在尝试在SQL中连接两个表,一个包含项目列表,另一个包含它们的销售日期。我得到了连接部分,但是我需要从REPORT表中获取信息,但是需要VENDORS表中的所有项目。我需要未售出的商品显示为NULL,或者最好是0.这是我到目前为止使用的代码,它只显示在给定日期销售的商品。
SELECT t2.[DATE]
,t1.[VENDOR]
,t1.[UPC]
,t2.[QTY]
,t2.[AMOUNT]
FROM [STORESQL].[dbo].[VENDORS] t1
LEFT OUTER JOIN [STORESQL].[dbo].[REPORT] t2 ON t1.UPC=t2.UPC
WHERE VENDOR='119828' AND DATE='2011-11-8'
表格的例子是
VENDORS:
VENDOR UPC
119828 1
119828 2
119828 3
REPORT:
DATE UPC QTY AMOUNT
2011-11-8 1 1 9.99
2011-11-8 3 2 18.98
当前代码导致
DATE VENDOR UPC QTY AMOUNT
2011-11-8 119828 1 1 9.99
2011-11-8 119828 3 2 18.98
我需要它来显示
DATE VENDOR UPC QTY AMOUNT
2011-11-8 119828 1 1 9.99
2011-11-8 119828 2 0 0.00
2011-11-8 119828 3 2 18.98
我知道我做错了什么,但我不知道那是什么。 提前谢谢。
答案 0 :(得分:5)
请改为尝试:
SELECT t2.[DATE]
,t1.[VENDOR]
,t1.[UPC]
,t2.[QTY]
,t2.[AMOUNT]
FROM [STORESQL].[dbo].[VENDORS] t1
LEFT OUTER JOIN [STORESQL].[dbo].[REPORT] t2 ON t1.UPC=t2.UPC AND DATE='2011-11-8'
WHERE VENDOR='119828'
针对DATE的where子句使您的外连接充当内连接,因为比较将在DATE中与空值相对。将比较移到ON子句应该处理。
要获得0而不是null,您可以使用COALESCE:
,COALESCE(t2.[QTY], 0)
,COALESCE(t2.[AMOUNT], 0)
您的日期列也将为空,也可以使用COALESCE修复:
COALESCE(t2.[DATE], '2011-11-8')
答案 1 :(得分:1)
这是不兼容的:
WHERE t2.DATE='2011-11-8'
第一个WHERE
子句将取消OUTER JOIN的所有效果,因为您删除了T1
中与您的行不匹配的所有记录。也许你想要:
WHERE VENDOR='119828' AND (DATE='2011-11-8' OR DATE IS NULL)
答案 2 :(得分:0)
WITH VENDORS
AS
(
SELECT *
FROM (
VALUES (119828, 1),
(119828, 2),
(119828, 3)
) AS T (VENDOR, UPC)
),
REPORT
AS
(
SELECT *
FROM (
VALUES ('2011-11-08T00:00:00', 1, 1, 9.99),
('2011-11-08T00:00:00', 3, 2, 18.98)
) AS T ("DATE", UPC, QTY, AMOUNT)
),
AllReportDates
AS
(
SELECT DISTINCT "DATE"
FROM REPORT
)
SELECT r."DATE", v.VENDOR, v.UPC, r.QTY, r.AMOUNT
FROM VENDORS v
JOIN REPORT r
ON v.UPC = r.UPC
UNION
SELECT a."DATE", v.VENDOR, v.UPC, 0 AS QTY, 0.00 AS AMOUNT
FROM VENDORS v
CROSS JOIN AllReportDates a
WHERE NOT EXISTS (
SELECT *
FROM REPORT r
WHERE r.UPC = v.UPC
AND r."DATE" = a."DATE"
);