EXISTS子句ISSUE与子查询中的TOP子句一起使用



我在下面有一个查询子查询(目的是从freight_charges=2的订单表中搜索前2个订单,并获得这些订单的客户(

  1. 使用IN子句处理查询
SELECT *
FROM Customers C
WHERE C.CUST_ID IN (
SELECT TOP 2 CUST_ID
FROM Orders O
where FREIGHT_CHARGES = 2
) 

然而,我想将IN子句转换为更高效的EXISTS子句

  1. 代码无法使用exists子句
SELECT *
FROM Customers C
WHERE EXISTS (
SELECT TOP 2 CUST_ID
FROM Orders O
where FREIGHT_CHARGES = 2 AND C.CUST_ID = O.CUST_ID
)

在第二个查询的情况下,我不是检索前2个cust_id,而是检索所有记录。

请让我知道任何实现以获得期望的结果。

编辑:按照答案中的建议使用INNER JOIN。我能够得到正确的结果。然而,由于我不想从Orders表中检索任何记录,我认为从性能角度来看,存在是一种更好的方法。

SELECT C.*
FROM Customers C
INNER JOIN (
SELECT TOP 2 CUST_ID
FROM Orders 
where FREIGHT_CHARGES = 2
) O ON C.CUST_ID=O.CUST_ID

如果将EXISTS与TOP混合使用,则与不使用TOP没有区别,因为EXISTS"如果子查询包含任何行,则返回TRUE"。

在您的情况下,您可以检查查询:

SELECT *
FROM Customers C
WHERE EXISTS (
SELECT 1
FROM Orders O
JOIN Orders O2
ON O.FREIGHT_CHARGES = O2.FREIGHT_CHARGES 
AND O.CUST_ID = O.CUST_ID
AND O.ID <> O2.ID
where O.FREIGHT_CHARGES = 2 AND C.CUST_ID = O.CUST_ID
)

SELECT *
FROM Customers C
WHERE EXISTS (
SELECT 1
FROM Orders O
where FREIGHT_CHARGES = 2 AND C.CUST_ID = O.CUST_ID
GROUP BY FREIGHT_CHARGES, CUST_ID
HAVING COUNT(1) > 1
)

你必须测试哪一个在你的情况下更好

我可以建议您选择INNER JOIN。如果可能的话,最好避免子查询,因为它是针对主表中的每一行执行的,因为它处于WHERE条件下。相反,您可以使用简单的INNER JOIN来获得所需的输出。

与您的示例一样,您只需要TOP 2客户的FREIGHT_CHARGES值为2。您可以使用INNER JOIN使用以下查询。

SELECT
TOP 2
C.*
FROM Customers C
INNER JOIN Orders O ON C.CUST_ID = O.CUST_ID
WHERE O.FREIGHT_CHARGES = 2
ORDER BY C.CUST_ID -- Use 'ORDER BY' clause if 'C.CUST_ID' column does not have clustered index or you can use any other column

请告诉我你的反馈。

EXISTS运算符是一个逻辑运算符,允许您检查子查询是否返回任何行。如果子查询至少返回一行或多行,EXISTS运算符将返回TRUE。

因此,由于Order表中FREIGHT_CHARGES=2的每一行都将为EXISTS语句返回TRUE(如果是TOP 2,则1就足够了(,因此结果包括Customers表中Orders中具有正确CUST_ID的每一条记录。

在您的情况下,EXISTS对您来说不是一个好选择。

请查看此链接:https://www.sqlservertutorial.net/sql-server-basics/sql-server-exists/

SELECT Top 2 *
FROM Customers as C
WHERE EXISTS (
SELECT O.CUST_ID
FROM Orders as O
where FREIGHT_CHARGES = 2 AND C.CUST_ID = O.CUST_ID
)

最新更新