【问题标题】:How to write a SQL query with no duplicates如何编写没有重复的 SQL 查询
【发布时间】:2019-12-16 15:45:56
【问题描述】:

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

有两张桌子。表 1 CUSTOMERS 和表 2 ORDERS

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

CUSTOMERS 表中的 ID 是主键,ORDERS 表的 ID_CUSTOMER 是外键 我应该如何编写查询以显示订购了“Apple MacBook Air 13”且不重复的客户的 ID?

 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 和 joins ?

【问题讨论】:

    标签: mysql sql distinct-values


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        在这个查询中:

        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'; 
        

        【讨论】:

          【解决方案4】:

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

          关于您的查询:您为什么要加入客户表?它没有提供我们已经从订单表中获得的任何东西。您的查询可以缩短为:

          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”行,最后只删除了其中的一些甚至许多行。

          我们可以用不同的方式编写查询来避免这种情况。我们从客户表开始,并显示我们在“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'
          );
          

          在这些查询中,我们仅从客户表中进行选择(此处为 ID,但我们也可以显示客户的姓名等)并使用订单表进行查找。一旦 DBMS 为客户找到“Apple MacBook Air 13”订单,它就不必为同一客户寻找更多此类订单。这样可以节省不少时间。而且我们只获得每个客户一次,不必申请DISTINCT(所有结果行都必须进行排序和比较)。查询也非常易读(虽然有点长),因为我们清楚地区分了我们从哪个表中选择行(FROM 子句)和搜索条件是什么(WHERE 子句)。

          【讨论】:

            猜你喜欢
            • 2021-03-20
            • 1970-01-01
            • 2013-07-13
            • 1970-01-01
            • 2022-01-18
            • 1970-01-01
            • 2020-10-04
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多