我想要报告在特定时期内没有销售的品牌。这是我到目前为止尝试过的方法,但是我得到了一个空列Brand_Name
。
SELECT DISTINCT
Brands$.BRAND_NAME
FROM
Brands$
INNER JOIN
Products$ ON Brands$.BRAND_ID = Products$.BRAND_ID
LEFT JOIN
InvDetails$ ON Products$.PRODUCT_ID = InvDetails$.PRODUCT_ID
INNER JOIN
Invoices$ ON Invoices$.INVOICE_ID = InvDetails$.INVOICE_ID
WHERE
InvDetails$.PRODUCT_ID IS NULL
AND (Invoices$.INVOICE_DATE BETWEEN '2013-10-22 23:41:49.143'
AND '2013-11-22 17:54:03.437')
答案 0 :(得分:0)
您应在ON子句中移动左连接表的条件
SELECT DISTINCT Brands$.BRAND_NAME
FROM Brands$
INNER JOIN Products$ ON Brands$.BRAND_ID=Products$.BRAND_ID
LEFT JOIN InvDetails$ ON Products$.PRODUCT_ID=InvDetails$.PRODUCT_ID
AND InvDetails$.PRODUCT_ID IS NULL
INNER JOIN Invoices$ ON Invoices$.INVOICE_ID=InvDetails$.INVOICE_ID
AND (Invoices$.INVOICE_DATE BETWEEN '2013-10-22 23:41:49.143' AND '2013-11-22 17:54:03.437')
如果您将where与左连接表相关的列一起使用,则可以用作内部连接
答案 1 :(得分:0)
我认为您只需要两个LEFT JOIN
,并将发票上的条件移至ON
子句;
SELECT DISTINCT b.BRAND_NAME
FROM Brands$ b JOIN
Products$ p
ON b.BRAND_ID = p.BRAND_ID LEFT JOIN
InvDetails$ id
ON p.PRODUCT_ID = id.PRODUCT_ID LEFT JOIN
Invoices$ i
ON i.INVOICE_ID = id.INVOICE_ID AND
i.INVOICE_DATE BETWEEN '2013-10-22 23:41:49.143' AND '2013-11-22 17:54:03.437'
WHERE id.PRODUCT_ID IS NULL;
表别名使查询更易于编写和阅读。
答案 2 :(得分:0)
与此:
SELECT DISTINCT Brands$.BRAND_NAME
FROM Brands$
INNER JOIN Products$ ON Brands$.BRAND_ID = Products$.BRAND_ID
INNER JOIN InvDetails$ ON Products$.PRODUCT_ID = InvDetails$.PRODUCT_ID
INNER JOIN Invoices$ ON Invoices$.INVOICE_ID = InvDetails$.INVOICE_ID
WHERE Invoices$.INVOICE_DATE BETWEEN '2013-10-22 23:41:49.143' AND '2013-11-22 17:54:03.437'
您获得在特定时期内有销售的产品。
因此,使用EXCEPT
:
SELECT Brands$.BRAND_NAME
FROM Brands$
EXCEPT
SELECT DISTINCT Brands$.BRAND_NAME
FROM Brands$
INNER JOIN Products$ ON Brands$.BRAND_ID = Products$.BRAND_ID
INNER JOIN InvDetails$ ON Products$.PRODUCT_ID = InvDetails$.PRODUCT_ID
INNER JOIN Invoices$ ON Invoices$.INVOICE_ID = InvDetails$.INVOICE_ID
WHERE Invoices$.INVOICE_DATE BETWEEN '2013-10-22 23:41:49.143' AND '2013-11-22
您将获得在此特定时期内没有销售的所有产品。
答案 3 :(得分:0)
另外,当尝试从一个表中查找记录而在另一表NOT EXISTS
will perform better on SQL Server than LEFT JOIN\IS NULL
中没有相应记录时,我发现它传达的意图更加清晰,例如
SELECT b.BRAND_NAME
FROM Brands$ AS b
WHERE NOT EXISTS
( SELECT 1
FROM Products$ AS p
INNER JOIN InvDetails$ AS id
ON id.PRODUCT_ID = p.PRODUCT_ID
INNER JOIN Invoices$ AS i
ON i.INVOICE_ID = id.INVOICE_ID
WHERE i.INVOICE_DATE BETWEEN '2013-10-22 23:41:49.143' AND '2013-11-22 17:54:03.437'
WHERE p.BRAND_ID = b.BRAND_ID
);
在某些情况下,两者之间没有性能差异,但是在这种情况下,我绝对希望NOT EXISTS
的性能更好,因为至少您已删除了删除重复记录的需要。
答案 4 :(得分:0)
我正在使用NOT EXISTS排除指定时期内带有发票的任何品牌
SELECT DISTINCT b.BRAND_NAME
FROM Brands$ b
INNER JOIN Products$ p ON b.BRAND_ID=p.BRAND_ID
WHERE NOT EXISTS(SELECT 1
FROM Invoices$ i
JOIN InvDetails$ id ON i.INVOICE_ID = id.INVOICE_ID
WHERE i.INVOICE_DATE BETWEEN '2013-10-22 23:41:49.143' AND '2013-11-22 17:54:03.437'
AND id.PRODUCT_ID = p.PRODUCT_ID)
答案 5 :(得分:0)
使用发票查找品牌并排除。
SELECT B.BRAND_NAME FROM Brands$ B
LEFT JOIN (
SELECT Brands$.BRAND_NAME
FROM Brands$
INNER JOIN Products$ ON Brands$.BRAND_ID=Products$.BRAND_ID
JOIN InvDetails$ ON Products$.PRODUCT_ID=InvDetails$.PRODUCT_ID
JOIN Invoices$ ON Invoices$.INVOICE_ID=InvDetails$.INVOICE_ID
WHERE InvDetails$.PRODUCT_ID IS NULL AND (Invoices$.INVOICE_DATE BETWEEN '2013-10-22 23:41:49.143' AND '2013-11-22 17:54:03.437')
GROUP BY Brands$.BRAND_NAME ) T ON B.BRAND_NAME = T.BRAND_NAME
WHERE T.BRAND_NAME IS NULL
与数字名称相比,数字ID必须更快地进行比较。