SQL完全加入Where

时间:2011-11-08 21:37:20

标签: sql join left-join

我正在尝试在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

我知道我做错了什么,但我不知道那是什么。 提前谢谢。

3 个答案:

答案 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'
  • 我需要未售出的商品显示为NULL

第一个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"
                  );