查询SQL时结果为空

时间:2019-02-14 12:32:21

标签: sql sql-server

我想要报告在特定时期内没有销售的品牌。这是我到目前为止尝试过的方法,但是我得到了一个空列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')

6 个答案:

答案 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必须更快地进行比较。