Leetcode183.从不订购的客户(简单)

题目

某网站包含两个表,Customers 表和 Orders 表。编写一个 SQL 查询,找出所有从不订购任何东西的客户。

Customers 表:

+----+-------+
| Id | Name  |
+----+-------+
| 1  | Joe   |
| 2  | Henry |
| 3  | Sam   |
| 4  | Max   |
+----+-------+

Orders 表:

+----+------------+
| Id | CustomerId |
+----+------------+
| 1  | 3          |
| 2  | 1          |
+----+------------+

例如给定上述表格,你的查询应返回:

+-----------+
| Customers |
+-----------+
| Henry     |
| Max       |
+-----------+

审题
翻译一下题目,其实不就是要出现在Customers,但是不出现在Orders中的结果
这不就是两表连接中的这种情况,其实不分析出这种情况也很好写

构造数据

CREATE TABLE Customers(
Id INT,
NAME VARCHAR(20));

CREATE TABLE Orders(
Id INT,
 CustomerId INT);
 
INSERT INTO Customers VALUE(1, 'Joe'),(2, 'Henry'),(3, 'Sam'),(4, 'Max');
 
INSERT INTO Orders VALUE(1, 3),(2,1);

自己的解法
1、审题的思路

SELECT C.`Name` AS Customers
FROM Customers C 
LEFT JOIN Orders O
ON C.`Id` = O.`CustomerId`
WHERE O.`Id` IS NULL;

2.子查询也是可以实现的
①、先查出所有有订单的顾客编号

SELECT CustomerId
FROM Orders;

②、选出编号不为①结果的顾客姓名

SELECT 
  c.`Name` as 'Customers'
FROM
  customers AS c 
WHERE c.`Id` NOT IN 
  (SELECT 
    CustomerId 
  FROM
    Orders);

别的解法
1.左连接的优化
先用子查询将买过东西的顾客id选出来。 在应用left join

SELECT C.`Name` AS Customers
FROM Customers C 
LEFT JOIN (SELECT DISTINCT CustomerId FROM Orders) O
ON C.`Id` = O.`CustomerId`
WHERE O.`CustomerId` IS NULL;

EXISTS是布尔运算符,常用于测试子查询。

SELECT 
    select_list
FROM
    a_table
WHERE
    [NOT] EXISTS(subquery);

当subquery返回任何行时,EXISTS返回true,否则返回false。

因此得出下述算法。

SELECT 
  C.`Name` AS Customers 
FROM
  customers AS C 
WHERE NOT EXISTS 
  (SELECT 
    o.`CustomerId` 
  FROM
    orders AS o 
  WHERE C.`Id` = o.`CustomerId`) ;

你可能感兴趣的:(Leetcode183.从不订购的客户(简单))