如何编写没有重复的 SQL 查询

How to write a SQL query with no duplicates

如何正确编写没有重复的 SQL 查询?

有两个table。 Table 1 位客户和 table 2 位订单

CUSTOMERS (ID, FIRSTNAME, LASTNAME, ADDRESS); 
ORDERS (ID, PRODUCT_NAME, PRODUCT_PRICE, DATE_ORDER, ID_CUSTOMER, AMOUNT);

CUSTOMERStable中的ID是主键,ORDERStable中有ID_CUSTOMER外键 我应该如何编写一个查询来显示没有重复的客户的 ID,他们已经订购了 'Apple MacBook Air 13'?

 CUSTOMERS (ID, FIRSTNAME, LASTNAME, ADDRESS); 
 ORDERS (ID, PRODUCT_NAME, PRODUCT_PRICE, DATE_ORDER, ID_CUSTOMER, AMOUNT); 

SELECT DISTINCT CUSTOMERS.ID, ORDERS.PRODUCT_NAME 
FROM CUSTOMERS 
INNER JOIN ORDERS 
ON CUSTOMERS.ID = ORDERS.ID_CUSTOMERS
WHERE PRODUCT_NAME = ‘Apple MacBook Air 13’; 

我写了一个查询,但似乎不清楚是否将 DISTINCT 运算符与 INNER JOIN 一起使用。是否可以有 DISTINCT 和连接?

你知道为什么是复制,对吧?这是因为对于每个客户,您可能有 1 个或多个 customers_orders.

因此,如果您仍想继续按产品过滤并删除重复项,您可以在这种情况下使用 DISTINCT 子句,并且在 SELECT 语句中仅引用 CUSTOMERS table 中的字段。如果 CUSTOMERS_ORDERS table 中的任何字段在 SELECT 上被引用,它将重复。

您可以将 DISTINCT 想象成一种输出过滤器的形式,它在查询本身完成时应用。 JOIN 用于构建查询的输入。 简短的回答是:是的,你可以做到。

在此查询中:

SELECT c.ID, o.PRODUCT_NAME 
FROM CUSTOMERS c INNER JOIN
     ORDERS o
     ON c.ID = o.ID_CUSTOMERS
WHERE o.PRODUCT_NAME = 'Apple MacBook Air 13'; 

对于多次订购该产品的客户,您可以获得重复的产品。使用 SELECT DISTINCT 你只会得到一行。

接下来,JOIN就没有必要了。你可以简单地做:

SELECT DISTINCT o.ID_CUSTOMERS, o.PRODUCT_NAME 
FROM ORDERS o
WHERE o.PRODUCT_NAME = 'Apple MacBook Air 13'; 

DISTINCT 是为了删除重复项。这有时很有用。但它也常常是一个写得不好的查询的指标,因为:为什么结果中首先有重复的行?

关于您的问题:您为什么加入客户table?它不提供我们从订单 table 中没有得到的任何东西。您的查询可以缩短为:

SELECT DISTINCT id_customers, 'Apple MacBook Air 13'
FROM orders 
WHERE product_name = 'Apple MacBook Air 13';

或者,因为它只涉及一种产品:

SELECT DISTINCT id_customers
FROM orders 
WHERE product_name = 'Apple MacBook Air 13';

我们在这里使用 DISTINCT,因为客户可以多次订购产品,因此会多次出现在结果中,我们没有使用 DISTINCT。但是,我们读取了所有 'Apple MacBook Air 13' 行,最后只删除了其中的一些甚至许多行。

我们可以编写不同的查询来避免这种情况。我们从客户 table 开始,并显示我们在 'Apple MacBook Air 13'.

上至少找到一个订单的那些 ID/行
SELECT id
FROM customers
WHERE id IN
(
  SELECT id_customers
  FROM orders
  WHERE product_name = 'Apple MacBook Air 13'
);

SELECT id
FROM customers c
WHERE EXISTS
(
  SELECT *
  FROM orders o
  WHERE o.id_customers = c.id
  AND o.product_name = 'Apple MacBook Air 13'
);

在这些查询中,我们仅 select 来自客户 table(此处为 ID,但我们也可以显示客户姓名等)并使用订单 table用于查找。一旦 DBMS 找到一个客户的 'Apple MacBook Air 13' 订单,它就不必为同一客户寻找更多此类订单。那可以节省不少时间。而且我们只获得每个客户一次,而不必应用 DISTINCT(为此所有结果行都必须进行排序和比较)。查询也非常可读(尽管有点长),因为我们清楚地将 table 我们正在 selecting 行与(FROM 子句)和搜索条件(WHERE 子句).