我在下面有一个查询子查询(目的是从freight_charges=2的订单表中搜索前2个订单,并获得这些订单的客户(
- 使用IN子句处理查询
SELECT *
FROM Customers C
WHERE C.CUST_ID IN (
SELECT TOP 2 CUST_ID
FROM Orders O
where FREIGHT_CHARGES = 2
)
然而,我想将IN子句转换为更高效的EXISTS子句
- 代码无法使用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
请告诉我你的反馈。
因此,由于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
)