【SQL】SQL常见面试题总结(1)

目录

  • 1、检索数据
    • 1.1、从 Customers 表中检索所有的 ID
    • 1.2、检索并列出已订购产品的清单
    • 1.2、检索所有列
  • 2、排序检索数据
    • 2.1、检索顾客名称并且排序
    • 2.2、对顾客 ID 和日期排序
    • 2.3、按照数量和价格排序
    • 2.4、检查 SQL 语句
  • 3、过滤数据
    • 3.1、返回固定价格的产品
    • 3.2、返回产品并且按照价格排序
    • 3.3、返回更多的产品
  • 4、高级数据过滤
    • 4.1、检索供应商名称
    • 4.2、检索并列出已订购产品的清单
    • 4.3、回所有价格在 3 美元到 6 美元之间的产品的名称和价格
    • 4.4、检查 SQL 语句
  • 5、用通配符进行过滤
    • 5.1、检索产品名称和描述(一)
    • 5.2、检索产品名称和描述(二)
    • 5.3、检索产品名称和描述(三)
    • 5.4、检索产品名称和描述(四)
  • 6、创建计算字段
    • 6.1、别名
    • 6.2、打折
  • 7、使用函数处理数据
    • 7.1、顾客登录名
    • 7.2、返回 2020 年 1 月的所有订单的订单号和订单日期
  • 8、汇总数据
    • 8.1、确定已售出产品的总数
    • 8.2、确定已售出产品项 BR01 的总数
    • 8.3、确定 Products 表中价格不超过 10 美元的最贵产品的价格
  • 9、分组数据
    • 9.1、返回每个订单号各有多少行数
    • 9.2、每个供应商成本最低的产品
    • 9.3、返回订单数量总和不小于 100 的所有订单的订单号
    • 9.4、计算总和
    • 9.5、检查 SQL 语句
  • 10、使用子查询
    • 10.1、返回购买价格为 10 美元或以上产品的顾客列表
    • 10.2、确定哪些订单购买了 prod_id 为 BR01 的产品(一)
    • 10.3、返回购买 prod_id 为 BR01 的产品的所有顾客的电子邮件(一)
    • 10.4、返回每个顾客不同订单的总金额
    • 10.5、从 Products 表中检索所有的产品名称以及对应的销售总数
  • 11、连接表
    • 11.1、返回顾客名称和相关订单号
    • 11.2、返回顾客名称和相关订单号以及每个订单的总价
    • 11.3、确定哪些订单购买了 prod_id 为 BR01 的产品(二)
    • 11.4、返回购买 prod_id 为 BR01 的产品的所有顾客的电子邮件(二)
    • 11.5、确定最佳顾客的另一种方式(二)
  • 12、创建高级连接
    • 12.1、检索每个顾客的名称和所有的订单号(一)
    • 12.2、检索每个顾客的名称和所有的订单号(二)
    • 12.3、返回产品名称和与之相关的订单号
    • 12.4、返回产品名称和每一项产品的总订单数
    • 12.5、列出供应商及其可供产品的数量
  • 13、组合查询
    • 13.1、将两个 SELECT 语句结合起来(一)
    • 13.2、将两个 SELECT 语句结合起来(二)
    • 13.3、组合 Products 表中的产品名称和 Customers 表中的顾客名称
    • 13.4、检查 SQL 语句

1、检索数据

SELECT 用于从数据库中查询数据。

1.1、从 Customers 表中检索所有的 ID

现有表 Customers 如下:

cust_id
A
B
C

编写 SQL 语句,从 Customers 表中检索所有的 cust_id

答案:

SELECT cust_id
FROM Customers

在这里插入图片描述

1.2、检索并列出已订购产品的清单

OrderItems 含有非空的列 prod_id 代表商品 id,包含了所有已订购的商品(有些已被订购多次)。

prod_id
a1
a1
a2
a3
a4
a5
a6
a7

编写 SQL 语句,检索并列出所有已订购商品(prod_id)的去重后的清单。

答案:

SELECT DISTINCT prod_id
FROM OrderItems

在这里插入图片描述

知识点:DISTINCT 用于返回列中的唯一不同值。

1.2、检索所有列

现在有 Customers 表(表中含有列 cust_id 代表客户 idcust_name 代表客户姓名)

cust_idcust_name
a1andy
a2ben
a3tony
a4tom
a5an
a6lee
a7hex

需要编写 SQL 语句,检索所有列。

答案:

SELECT cust_id, cust_name      
FROM Customers

在这里插入图片描述

2、排序检索数据

ORDER BY 用于对结果集按照一个列或者多个列进行排序。默认按照升序对记录进行排序,如果需要按照降序对记录进行排序,可以使用 DESC 关键字。

2.1、检索顾客名称并且排序

有表 Customerscust_id 代表客户 idcust_name 代表客户姓名。

cust_idcust_name
a1andy
a2ben
a3tony
a4tom
a5an
a6lee
a7hex

Customers 中检索所有的顾客名称(cust_name),并按从 Z 到 A 的顺序显示结果。

答案:

SELECT cust_id, cust_name      
FROM Customers
ORDER BY cust_name DESC

在这里插入图片描述

2.2、对顾客 ID 和日期排序

Orders 表:

cust_idorder_numorder_date
andyaaaa2021-01-01 00:00:00
andybbbb2021-01-01 12:00:00
bobcccc2021-01-10 12:00:00
dickdddd2021-01-11 00:00:00

编写 SQL 语句,从 Orders 表中检索顾客 ID(cust_id)和订单号(order_num),并先按顾客 ID 对结果进行排序,再按订单日期倒序排列。

答案:

# 根据列名排序
# 注意:是 order_date 降序,而不是 order_num
SELECT cust_id,order_num
FROM Orders
ORDER BY cust_id,order_date DESC

在这里插入图片描述

知识点:order by 对多列排序的时候,先排序的列放前面,后排序的列放后面。并且,不同的列可以有不同的排序规则。

2.3、按照数量和价格排序

假设有一个 OrderItems 表:

quantityitem_price
1100
101003
2500

编写 SQL 语句,显示 OrderItems 表中的数量(quantity)和价格(item_price),并按数量由多到少、价格由高到低排序。

答案:

SELECT quantity,item_price
FROM OrderItems
ORDER BY quantity DESC,item_price DESC

在这里插入图片描述

知识点:order by 对多列排序的时候,先排序的列放前面,后排序的列放后面。并且,不同的列可以有不同的排序规则。

例如:

在这里插入图片描述
按照上述代码查询:

在这里插入图片描述

2.4、检查 SQL 语句

Vendors 表:

vend_name
海底捞
小龙坎
大龙燚

下面的 SQL 语句有问题吗?尝试将它改正确,使之能够正确运行,并且返回结果根据vend_name 逆序排列。

SELECT vend_name,
FROM Vendors
ORDER vend_name DESC

在这里插入图片描述

改正后:

SELECT vend_name
FROM Vendors
ORDER vend_name DESC

在这里插入图片描述

知识点:

  • 逗号作用是用来隔开列与列之间的。
  • ORDER BY 是有 BY 的,需要撰写完整,且位置正确。

3、过滤数据

WHERE 可以过滤返回的数据。

下面的运算符可以在 WHERE 子句中使用:

运算符描述
=等于
<>不等于。 注释: 在 SQL 的一些版本中,该操作符可被写成 !=
>大于
<小于
>=大于等于
<=小于等于
BETWEEN在某个范围内
LIKE搜索某种模式
IN指定针对某个列的多个可能值

3.1、返回固定价格的产品

有表 Products

prod_idprod_nameprod_price
a0018sockets9.49
a0019iphone13600
b0018gucci t-shirts1000

【问题】从 Products 表中检索产品 ID(prod_id)和产品名称(prod_name),只返回价格为 9.49 美元的产品。

答案:

SELECT prod_id,prod_name
FROM Products
WHERE prod_price>=9.49

在这里插入图片描述

3.2、返回产品并且按照价格排序

有表 Products

prod_idprod_nameprod_price
a0011egg3
a0019sockets4
b0019coffee15

【问题】编写 SQL 语句,返回 Products 表中所有价格在 3 美元到 6 美元之间的产品的名称(prod_name)和价格(prod_price),然后按价格对结果进行排序。

答案:

SELECT prod_id,prod_name
FROM Products
WHERE prod_price BETWEEN 3 AND 6
ORDER BY prod_price

SELECT prod_id,prod_name
FROM Products
WHERE prod_price>=3 AND prod_price <= 6
ORDER BY prod_price

在这里插入图片描述

3.3、返回更多的产品

OrderItems 表含有:订单号 order_numquantity产品数量

order_numquantity
a1105
a21100
a2200
a41121
a510
a219
a75

【问题】从 OrderItems 表中检索出所有不同且不重复的订单号(order_num),其中每个订单都要包含 100 个或更多的产品。

答案:

SELECT order_num
FROM OrderItems
GROUP BY order_num
HAVING SUM(quantity) >= 100

在这里插入图片描述

4、高级数据过滤

AND OR 运算符用于基于一个以上的条件对记录进行过滤,两者可以结合使用。AND 必须 2 个条件都成立,OR只要 2 个条件中的一个成立即可。

4.1、检索供应商名称

Vendors 表有字段供应商名称(vend_name)、供应商国家(vend_country)、供应商州(vend_state

vend_namevend_countryvend_state
appleUSACA
vivoCNAshenzhen
huaweiCNAxian

【问题】编写 SQL 语句,从 Vendors 表中检索供应商名称(vend_name),仅返回加利福尼亚州的供应商(这需要按国家[USA]和州[CA]进行过滤,没准其他国家也存在一个 CA)

答案:

SELECT vend_name
FROM Vendors
WHERE vend_country = "USA" AND vend_state = "CA"

在这里插入图片描述

4.2、检索并列出已订购产品的清单

OrderItems 表包含了所有已订购的产品(有些已被订购多次)。

prod_idorder_numquantity
BR01a1105
BR02a21100
BR02a2200
BR03a41121
BR017a510
BR02a219
BR017a75

【问题】编写 SQL 语句,查找所有订购了数量至少 100 个的 BR01BR02BR03 的订单。你需要返回 OrderItems 表的订单号(order_num)、产品 ID(prod_id)和数量(quantity),并按产品 ID 和数量进行过滤。

答案:

SELECT order_num,prod_id,quantity
FROM OrderItems
WHERE prod_id IN (`BR01`,`BR02`,`BR03`) AND quantity >= 100

在这里插入图片描述

4.3、回所有价格在 3 美元到 6 美元之间的产品的名称和价格

有表 Products

prod_idprod_nameprod_price
a0011egg3
a0019sockets4
b0019coffee15

【问题】编写 SQL 语句,返回所有价格在 3 美元到 6 美元之间的产品的名称(prod_name)和价格(prod_price),使用 AND 操作符,然后按价格对结果进行升序排序。

答案:

SELECT prod_name,prod_price
FROM Products
WHERE prod_price >= 3 AND prod_price <= 6
ORDER BY prod_price

在这里插入图片描述

4.4、检查 SQL 语句

Vendors 表有字段供应商名称(vend_name)、供应商国家(vend_country)、供应商州(vend_state

vend_namevend_countryvend_state
appleUSACA
vivoCNAshenzhen
huaweiCNAxian

【问题】修改正确下面 sql,使之正确返回。

SELECT vend_name
FROM Vendors
ORDER BY vend_name
WHERE vend_country = 'USA' AND vend_state = 'CA';

修改后:

SELECT vend_name
FROM Vendors
WHERE vend_country = 'USA' AND vend_state = 'CA'
ORDER BY vend_name

ORDER BY 语句必须放在 WHERE 之后。

5、用通配符进行过滤

SQL 通配符必须与LIKE运算符一起使用

在 SQL 中,可使用以下通配符:

通配符描述
%代表零个或多个字符
_仅替代一个字符
[charlist]字符列中的任何单一字符
[^charlist] 或者 [!charlist]不在字符列中的任何单一字符

5.1、检索产品名称和描述(一)

Products 表如下:

prod_nameprod_desc
a0011usb
a0019iphone13
b0019gucci t-shirts
c0019gucci toy
d0019lego toy

【问题】编写 SQL 语句,从 Products 表中检索产品名称(prod_name)和描述(prod_desc),仅返回描述中包含 toy 一词的产品名称。

答案:

SELECT prod_name,prod_desc
FROM Products
WHERE prod_desc LIKE '%toy%'

在这里插入图片描述

5.2、检索产品名称和描述(二)

Products 表如下:

prod_nameprod_desc
a0011usb
a0019iphone13
b0019gucci t-shirts
c0019gucci toy
d0019lego toy

【问题】编写 SQL 语句,从 Products 表中检索产品名称(prod_name)和描述(prod_desc),仅返回描述中未出现 toy 一词的产品,最后按”产品名称“对结果进行排序。

答案:

SELECT prod_name,prod_desc
FROM Products
WHERE prod_desc NOT LIKE '%toy%'
ORDER BY prod_name

在这里插入图片描述

5.3、检索产品名称和描述(三)

Products 表如下:

prod_nameprod_desc
a0011usb
a0019iphone13
b0019gucci t-shirts
c0019gucci toy
d0019lego carrots toy

【问题】编写 SQL 语句,从 Products 表中检索产品名称(prod_name)和描述(prod_desc),仅返回描述中同时出现 toycarrots 的产品。有好几种方法可以执行此操作,但对于这个挑战题,请使用 AND 和两个 LIKE 比较。

答案:

SELECT prod_name,prod_desc
FROM Products
WHERE prod_desc LIKE "%toy%" AND prod_desc LIKE "%carrots%"

在这里插入图片描述

5.4、检索产品名称和描述(四)

Products 表如下:

prod_nameprod_desc
a0011usb
a0019iphone13
b0019gucci t-shirts
c0019gucci toy
d0019lego toy carrots

【问题】编写 SQL 语句,从 Products 表中检索产品名称(prod_name)和描述(prod_desc),仅返回在描述中以先后顺序同时出现toycarrots的产品。提示:只需要用带有三个 % 符号的 LIKE 即可。

答案:

SELECT prod_name,prod_desc
FROM Products
WHERE prod_desc LIKE '%toy%carrots%'

在这里插入图片描述

6、创建计算字段

6.1、别名

别名的常见用法是在检索出的结果中重命名表的列字段(为了符合特定的报表要求或客户需求)。有表 Vendors 代表供应商信息,vend_id 供应商 idvend_name 供应商名称、vend_address 供应商地址、vend_city 供应商城市。

vend_idvend_namevend_addressvend_city
a001tencent cloudaddress1shenzhen
a002huawei cloudaddress2dongguan
a003aliyun cloudaddress3hangzhou
a003netease cloudaddress4guangzhou

【问题】编写 SQL 语句,从 Vendors 表中检索 vend_idvend_namevend_addressvend_city,将 vend_name 重命名为 vname,将 vend_city 重命名为 vcity,将 vend_address 重命名为 vaddress,按供应商名称对结果进行升序排序。

答案:

SELECT vend_id,vend_name AS vname,vend_address AS vaddress,vend_city AS vcity
FROM Vendors 
ORDER BY vname
# as 也可以省略
SELECT vend_id, vend_name vname, vend_address vaddress, vend_city vcity
FROM Vendors
ORDER BY vname

在这里插入图片描述

6.2、打折

我们的示例商店正在进行打折促销,所有产品均降价 10%。Products 表包含 prod_id 产品 id、prod_price 产品价格。

有表 Products

prod_idprod_nameprod_price
a0011egg3
a0019sockets4
b0019coffee15

【问题】编写 SQL 语句,从 Products 表中返回 prod_idprod_price sale_pricesale_price 是一个包含促销价格的计算字段。提示:可以乘以 0.9,得到原价的 90%(即 10%的折扣)。

答案:

SELECT prod_id,prod_price ,0.9*prod_price AS sale_price
FROM Products 

在这里插入图片描述

注意:sale_price 是对计算结果的命名,而不是原有的列名。

7、使用函数处理数据

7.1、顾客登录名

我们的商店已经上线了,正在创建顾客账户。所有用户都需要登录名,默认登录名是其名称和所在城市的组合。

给出 Customers 表 如下:

cust_idcust_namecust_contactcust_city
a1Andy LiAndy LiOak Park
a2Ben LiuBen LiuOak Park
a3Tony DaiTony DaiOak Park
a4Tom ChenTom ChenOak Park
a5An LiAn LiOak Park
a6Lee ChenLee ChenOak Park
a7Hex LiuHex LiuOak Park

【问题】编写 SQL 语句,返回顾客 ID(cust_id)、顾客名称(cust_name)和登录名(user_login),其中登录名全部为大写字母,并由顾客联系人的前两个字符(cust_contact)和其所在城市的前三个字符(cust_city)组成。提示:需要使用函数、拼接和别名。

答案:

SELECT cust_id,cust_name,UPPER(CONCAT(SUBSTRING(cust_contact,1,2),SUBSTRING(cust_city,1,3))) AS user_login
FROM Customers

在这里插入图片描述

知识点:

  • 截取函数SUBSTRING():截取字符串,substring(str ,n ,m)(n 表示起始截取位置,m 表示要截取的字符个数)表示返回字符串 str 从第 n 个字符开始截取 m 个字符;

  • 拼接函数CONCAT():将两个或多个字符串连接成一个字符串,select concat(A,B):连接字符串 A 和 B。

  • 大写函数 UPPER():将指定字符串转换为大写。

7.2、返回 2020 年 1 月的所有订单的订单号和订单日期

Orders 订单表如下:

order_numorder_date
a00012020-01-01 00:00:00
a00022020-01-02 00:00:00
a00032020-01-01 12:00:00
a00042020-02-01 00:00:00
a00052020-03-01 00:00:00

【问题】编写 SQL 语句,返回 2020 年 1 月的所有订单的订单号(order_num)和订单日期(order_date),并按订单日期升序排序

答案:

SELECT order_num,order_date
FROM Orders
WHERE MONTH(order_date) = '01' AND YEAR(order_date) = '2020'
ORDER BY order_date

也可以用通配符来做:

SELECT order_num,order_date
FROM Orders
WHERE order_date LIKE '2020-01%'
ORDER BY order_date 

在这里插入图片描述

知识点:

  • 日期格式:YYYY-MM-DD
  • 时间格式:HH:MM:SS

日期和时间处理相关的常用函数:

函 数说 明
ADDDATE()增加一个日期(天、周等)
ADDTIME()增加一个时间(时、分等)
CURDATE()返回当前日期
CURTIME()返回当前时间
DATE()返回日期时间的日期部分
DATEDIFF计算两个日期之差
DATE_FORMAT()返回一个格式化的日期或时间串
DAY()返回一个日期的天数部分
DAYOFWEEK()对于一个日期,返回对应的星期几
HOUR()返回一个时间的小时部分
MINUTE()返回一个时间的分钟部分
MONTH()返回一个日期的月份部分
NOW()返回当前日期和时间
SECOND()返回一个时间的秒部分
TIME()返回一个日期时间的时间部分
YEAR()返回一个日期的年份部分

8、汇总数据

汇总数据相关的函数:

函 数说 明
AVG()返回某列的平均值
COUNT()返回某列的行数
MAX() 返回某列的最大值
MIN() 返回某列的最小值
SUM()返回某列值之和

8.1、确定已售出产品的总数

OrderItems 表代表售出的产品,quantity 代表售出商品数量。

quantity
10
100
1000
10001
2
15

【问题】编写 SQL 语句,确定已售出产品的总数。

答案:

SELECT SUM(quantity) AS	items_ordered
FROM OrderItems

8.2、确定已售出产品项 BR01 的总数

OrderItems 表代表售出的产品,quantity 代表售出商品数量,产品项为 prod_id

quantityprod_id
10AR01
100AR10
1000BR01
10001BR010

【问题】修改创建的语句,确定已售出产品项(prod_id)为"BR01"的总数。

答案:

SELECT SUM(quantity) AS items_order
FROM OrderItems
WHERE prod_id = 'BR01'

在这里插入图片描述

8.3、确定 Products 表中价格不超过 10 美元的最贵产品的价格

Products 表如下,prod_price 代表商品的价格。

prod_price
9.49
600
1000

【问题】编写 SQL 语句,确定 Products 表中价格不超过 10 美元的最贵产品的价格(prod_price)。将计算所得的字段命名为 max_price

答案:

SELECT MAX(prod_price) AS max_price
FROM Products
WHERE prod_price <= 10

在这里插入图片描述

9、分组数据

GROUP BY

  • GROUP BY 子句将记录分组到汇总行中。
  • GROUP BY 为每个组返回一个记录。
  • GROUP BY 通常还涉及聚合COUNT,MAX,SUM,AVG 等。
  • GROUP BY 可以按一列或多列进行分组。
  • GROUP BY 按分组字段进行排序后,ORDER BY 可以以汇总字段来进行排序。

HAVING

  • HAVING 用于对汇总的 GROUP BY 结果进行过滤。
  • HAVING 必须要与 GROUP BY 连用。
  • WHEREHAVING 可以在相同的查询中。

HAVING vs WHERE

  • WHERE:过滤指定的行,后面不能加聚合函数(分组函数)。
  • HAVING:过滤分组,必须要与 GROUP BY 连用,不能单独使用。

9.1、返回每个订单号各有多少行数

OrderItems 表包含每个订单的每个产品

order_num
a002
a002
a002
a004
a007

【问题】编写 SQL 语句,返回每个订单号(order_num)各有多少行数(order_lines),并按 order_lines 对结果进行升序排序。

答案:

SELECT order_num,COUNT(order_num) AS order_lines
FROM OrderItems 
GROUP BY order_num
ORDER BY order_lines

在这里插入图片描述
知识点:

  1. count(*),count(列名)都可以,区别在于,count(列名)是统计非 NULL 的行数;
  2. order by 最后执行,所以可以使用列别名;
  3. 分组聚合一定不要忘记加上 group by ,不然只会有一行结果。

9.2、每个供应商成本最低的产品

Products 表,含有字段 prod_price 代表产品价格,vend_id 代表供应商 id

vend_idprod_price
a0011100
a00190.1
b00191000
b00196980
b001920

【问题】编写 SQL 语句,返回名为 cheapest_item 的字段,该字段包含每个供应商成本最低的产品(使用 Products 表中的 prod_price),然后从最低成本到最高成本对结果进行升序排序。

答案:

SELECT vend_id, MIN(prod_price) AS cheapest_item
FROM Products
GROUP BY vend_id	
ORDER BY cheapest_item

在这里插入图片描述

9.3、返回订单数量总和不小于 100 的所有订单的订单号

OrderItems 代表订单商品表,包括:订单号 order_num 和订单数量 quantity。

order_numquantity
a1105
a21100
a2200
a41121
a510
a219
a75

【问题】请编写 SQL 语句,返回订单数量总和不小于 100 的所有订单号,最后结果按照订单号升序排序。

答案:

# 直接聚合
SELECT order_num
FROM OrderItems 
GROUP BY order_num
HAVING SUM(quantity) >= 100
ORDER BY order_num

# 子查询
SELECT a.order_num
FROM ( SELECT order_num,SUM(quantity) AS sun_num 
			FROM OrderItems
			GROUP BY order_num
			HAVING sun_num >= 100) a
ORDER BY a.order_num

在这里插入图片描述

知识点:

  • where:过滤过滤指定的行,后面不能加聚合函数(分组函数)。
  • having:过滤分组,与 group by 连用,不能单独使用。

9.4、计算总和

OrderItems 表代表订单信息,包括字段:订单号 order_numitem_price 商品售出价格、quantity 商品数量。

order_numitem_pricequantity
a110105
a211100
a21200
a421121
a5510
a2119
a775

【问题】编写 SQL 语句,根据订单号聚合,返回订单总价不小于 1000 的所有订单号,最后的结果按订单号进行升序排序。

提示:总价 = item_price 乘以 quantity

答案:

SELECT order_num,SUM(item_price * quantity) AS total_price
FROM OrderItems
GROUP BY order_num
HAVING total_price >= 1000
ORDER BY order_num

在这里插入图片描述

9.5、检查 SQL 语句

OrderItems 表含有 order_num 订单号

order_num
a002
a002
a002
a004
a007

【问题】将下面代码修改正确后执行

SELECT order_num, COUNT(*) AS items
FROM OrderItems
GROUP BY items
HAVING COUNT(*) >= 3
ORDER BY items, order_num;

修改后:

SELECT order_num, COUNT(*) AS items
FROM OrderItems
GROUP BY order_num
HAVING items >= 3
ORDER BY items, order_num;

10、使用子查询

子查询是嵌套在较大查询中的 SQL 查询,也称内部查询或内部选择,包含子查询的语句也称为外部查询或外部选择。简单来说,子查询就是指将一个 SELECT 查询(子查询)的结果作为另一个 SQL 语句(主查询)的数据来源或者判断条件。

子查询可以嵌入 SELECTINSERTUPDATEDELETE 语句中,也可以和 =<>INBETWEENEXISTS 等运算符一起使用。

子查询常用在WHERE子句和FROM子句后边:

  • 当用于 WHERE 子句时,根据不同的运算符,子查询可以返回单行单列、多行单列、单行多列数据。子查询就是要返回能够作为 WHERE 子句查询条件的值。
  • 当用于 FROM 子句时,一般返回多行多列数据,相当于返回一张临时表,这样才符合 FROM 后面是表的规则。这种做法能够实现多表联合查询。

注意:MySQL 数据库从 4.1 版本才开始支持子查询,早期版本是不支持的。

用于 WHERE 子句的子查询的基本语法如下:

SELECT column_name [, column_name ]
FROM table1 [, table2 ]
WHERE column_name operator
(SELECT column_name [, column_name ]
FROM table1 [, table2 ]
[WHERE])
  • 子查询需要放在括号( )内。
  • operator 表示用于 WHERE 子句的运算符,可以是比较运算符(如 =, <, >, <> 等)或逻辑运算符(如 IN, NOT IN, EXISTS, NOT EXISTS 等),具体根据需求来确定。

用于 FROM 子句的子查询的基本语法如下:

SELECT column_name [, column_name ]
FROM (SELECT column_name [, column_name ]
      FROM table1 [, table2 ]
      [WHERE]) AS temp_table_name [, ...]
[JOIN type JOIN table_name ON condition]
WHERE condition;
  • 用于 FROM 的子查询返回的结果相当于一张临时表,所以需要使用 AS 关键字为该临时表起一个名字。
  • 子查询需要放在括号 ( ) 内。
  • 可以指定多个临时表名,并使用 JOIN 语句连接这些表。

10.1、返回购买价格为 10 美元或以上产品的顾客列表

OrderItems 表示订单商品表,含有字段订单号:order_num、订单价格:item_priceOrders 表代表订单信息表,含有顾客 id:cust_id 和订单号:order_num

OrderItems 表:

order_numitem_price
a110
a21
a21
a42
a55
a21
a77

Orders 表:

order_numcust_id
a1cust10
a2cust1
a2cust1
a4cust2
a5cust5
a2cust1
a7cust7

【问题】使用子查询,返回购买价格为 10 美元或以上产品的顾客列表,结果无需排序。

答案:

SELECT cust_id
FROM Orders
WHERE order_num in (SELECT DISTINCT order_num
		FROM OrderItems
		WHERE item_price >= 10)

10.2、确定哪些订单购买了 prod_id 为 BR01 的产品(一)

OrderItems 代表订单商品信息表,prod_id 为产品 id;Orders 表代表订单表有 cust_id 代表顾客 id 和订单日期 order_date

OrderItems 表:

prod_idorder_num
BR01a0001
BR01a0002
BR02a0003
BR02a0013

Orders 表:

order_numcust_idorder_date
a0001cust102022-01-01 00:00:00
a0002cust12022-01-01 00:01:00
a0003cust12022-01-02 00:00:00
a0013cust22022-01-01 00:20:00

【问题】

编写 SQL 语句,使用子查询来确定哪些订单(在 OrderItems 中)购买了 prod_id 为 “BR01” 的产品,然后从 Orders 表中返回每个产品对应的顾客 ID(cust_id)和订单日期(order_date),按订购日期对结果进行升序排序。

答案:

# 写法 1:子查询
SELECT cust_id,order_date
FROM Orders 
WHERE order_num IN 
		(SELECT order_num
		FROM OrderItems 
		WHERE prod_id = 'BR01')
ORDER BY order_date;

# 写法 2: 连接表
SELECT b.cust_id,b.order_date
FROM OrderItems a,Orders b
WHERE a.order_num = b.order_num AND a.prod_id = 'BR01'
ORDER BY b.order_date

在这里插入图片描述

10.3、返回购买 prod_id 为 BR01 的产品的所有顾客的电子邮件(一)

你想知道订购 BR01 产品的日期,有表 OrderItems 代表订单商品信息表,prod_id 为产品 id;Orders 表代表订单表有 cust_id 代表顾客 id 和订单日期 order_dateCustomers 表含有 cust_email 顾客邮件和 cust_id 顾客 id

OrderItems 表:

prod_idorder_num
BR01a0001
BR01a0002
BR02a0003
BR02a0013

Orders 表:

order_numcust_idorder_date
a0001cust102022-01-01 00:00:00
a0002cust12022-01-01 00:01:00
a0003cust12022-01-02 00:00:00
a0013cust22022-01-01 00:20:00

Customers 表代表顾客信息,cust_id 为顾客 id,cust_email 为顾客 email

cust_idcust_email
cust10cust10@cust.com
cust1cust1@cust.com
cust2cust2@cust.com

【问题】返回购买 prod_idBR01 的产品的所有顾客的电子邮件(Customers 表中的 cust_email),结果无需排序。

提示:这涉及 SELECT 语句,最内层的从 OrderItems 表返回 order_num,中间的从 Customers 表返回 cust_id

答案:

# 写法 1:子查询
SELECT cust_email
FROM Customers 
WHERE cust_id IN (SELECT cust_id
	FROM Orders 
	WHERE order_num IN (SELECT order_num
		FROM OrderItems 
		WHERE prod_id = 'BR01 '))

# 写法 2: 连接表(inner join)
SELECT cust_email
FROM OrderItems a,Orders b,Customers c
WHERE a.order_num = b.order_num AND b.cust_id = c.cust_id AND a.prod_id = 'BR01'

# 写法 3:连接表(left join)
SELECT cust_email
FROM OrderItems a
LEFT JOIN Orders b ON a.order_num = b.order_num
LEFT JOIN Customers c ON b.cust_id = c.cust_id
WHERE a.prod_id='BR01'

在这里插入图片描述

10.4、返回每个顾客不同订单的总金额

我们需要一个顾客 ID 列表,其中包含他们已订购的总金额。

OrderItems 表代表订单信息,OrderItems 表有订单号:order_num 和商品售出价格:item_price、商品数量:quantity

order_numitem_pricequantity
a000110105
a000211100
a00021200
a001321121
a0003510
a0003119
a000375

Orders 表订单号:order_num、顾客 id:cust_id

order_numcust_id
a0001cust10
a0002cust1
a0003cust1
a0013cust2

【问题】

编写 SQL 语句,返回顾客 ID(Orders 表中的 cust_id),并使用子查询返回total_ordered以便返回每个顾客的订单总数,将结果按金额从大到小排序。

答案:

# 写法 1:子查询
SELECT cust_id,tb.total_ordered
FROM (SELECT order_num, SUM(item_price * quantity) AS total_ordered
		FROM OrderItems
		GROUP BY order_num) as tb,
		Orders o
WHERE tb.order_num = o.order_num
ORDER BY tb.total_ordered DESC

# 写法 2:连接表
SELECT a.cust_id,SUM(b.item_price * b.quantity) AS total_ordered
FROM	OrderItems b
LEFT JOIN Orders a
ON a.order_num = b.order_num
GROUP BY cust_id
ORDER BY SUM(b.item_price * b.quantity)

在这里插入图片描述

10.5、从 Products 表中检索所有的产品名称以及对应的销售总数

Products 表中检索所有的产品名称:prod_name、产品 id:prod_id

prod_idprod_name
a0001egg
a0002sockets
a0013coffee
a0003cola

OrderItems 代表订单商品表,订单产品:prod_id、售出数量:quantity

prod_idquantity
a0001105
a00021100
a0002200
a00131121
a000310
a000319
a00035

【问题】

编写 SQL 语句,从 Products 表中检索所有的产品名称(prod_name),以及名为 quant_sold 的计算列,其中包含所售产品的总数(在OrderItems表上使用子查询和 SUM(quantity) 检索)。

答案:

# 写法 1:子查询
SELECT a.prod_name,b.quant_sold
FROM (SELECT prod_id,SUM(quantity) AS quant_sold
		FROM OrderItems 
		GROUP BY prod_id) AS b,Products a
WHERE b.prod_id = a.prod_id

# 写法 2:连接表
SELECT p.prod_name, Sum(o.quantity) AS quant_sold
FROM Products p,
  OrderItems o
WHERE p.prod_id = o.prod_id
GROUP BY p.prod_name(这里不能用 p.prod_id,会报错)

在这里插入图片描述

11、连接表

JOIN 是“连接”的意思,顾名思义,SQL JOIN 子句用于将两个或者多个表联合起来进行查询。

连接表时需要在每个表中选择一个字段,并对这些字段的值进行比较,值相同的两条记录将合并为一条。连接表的本质就是将不同表的记录合并起来,形成一张新表。当然,这张新表只是临时的,它仅存在于本次查询期间。

使用 JOIN 连接两个表的基本语法如下:

SELECT table1.column1, table2.column2...
FROM table1
JOIN table2
ON table1.common_column1 = table2.common_column2;

table1.common_column1 = table2.common_column2 是连接条件,只有满足此条件的记录才会合并为一行。您可以使用多个运算符来连接表,例如 =、>、<、<>、<=、>=、!=、betweenlike 或者 not,但是最常见的是使用 =。

当两个表中有同名的字段时,为了帮助数据库引擎区分是哪个表的字段,在书写同名字段名时需要加上表名。当然,如果书写的字段名在两个表中是唯一的,也可以不使用以上格式,只写字段名即可。

另外,如果两张表的关联字段名相同,也可以使用 USING子句来代替 ON,举个例子:

# join....on
SELECT c.cust_name, o.order_num
FROM Customers c
INNER JOIN Orders o
ON c.cust_id = o.cust_id
ORDER BY c.cust_name

# 如果两张表的关联字段名相同,也可以使用USING子句:JOIN....USING()
SELECT c.cust_name, o.order_num
FROM Customers c
INNER JOIN Orders o
USING(cust_id)
ORDER BY c.cust_name

ON WHERE 的区别:

  • 连接表时,SQL 会根据连接条件生成一张新的临时表。ON 就是连接条件,它决定临时表的生成。
  • WHERE 是在临时表生成以后,再对临时表中的数据进行过滤,生成最终的结果集,这个时候已经没有 JOIN-ON 了。

所以总结来说就是:SQL 先根据 ON 生成一张临时表,然后再根据 WHERE 对临时表进行筛选。

SQL 允许在 JOIN 左边加上一些修饰性的关键词,从而形成不同类型的连接,如下表所示:

连接类型说明
INNER JOIN 内连接(默认连接方式)只有当两个表都存在满足条件的记录时才会返回行。
LEFT JOIN / LEFT OUTER JOIN 左(外)连接返回左表中的所有行,即使右表中没有满足条件的行也是如此。
RIGHT JOIN / RIGHT OUTER JOIN 右(外)连接返回右表中的所有行,即使左表中没有满足条件的行也是如此。
FULL JOIN / FULL OUTER JOIN 全(外)连接只要其中有一个表存在满足条件的记录,就返回行。
SELF JOIN将一个表连接到自身,就像该表是两个表一样。为了区分两个表,在 SQL 语句中需要至少重命名一个表。
CROSS JOIN交叉连接,从两个或者多个连接表中返回记录集的笛卡尔积。

下图展示了 LEFT JOIN、RIGHT JOIN、INNER JOIN、OUTER JOIN 相关的 7 种用法。

在这里插入图片描述
如果不加任何修饰词,只写 JOIN,那么默认为 INNER JOIN

对于INNER JOIN来说,还有一种隐式的写法,称为 “隐式内连接”,也就是没有 INNER JOIN 关键字,使用 WHERE 语句实现内连接的功能

# 隐式内连接
SELECT c.cust_name, o.order_num
FROM Customers c,Orders o
WHERE c.cust_id = o.cust_id
ORDER BY c.cust_name

# 显式内连接
SELECT c.cust_name, o.order_num
FROM Customers c
INNER JOIN Orders o
USING(cust_id)
ORDER BY c.cust_name;

11.1、返回顾客名称和相关订单号

Customers 表有字段顾客名称 cust_name、顾客 id cust_id

cust_idcust_name
cust10andy
cust1ben
cust2tony
cust22tom
cust221an
cust2217hex

Orders 订单信息表,含有字段 order_num 订单号、cust_id 顾客 id

order_numcust_id
a1cust10
a2cust1
a3cust2
a4cust22
a5cust221
a7cust2217

【问题】编写 SQL 语句,返回 Customers 表中的顾客名称(cust_name)和 Orders 表中的相关订单号(order_num),并按顾客名称再按订单号对结果进行升序排序。你可以尝试用两个不同的写法,一个使用简单的等连接语法,另外一个使用 INNER JOIN。

答案:

# 隐式内连接
SELECT cust_name,order_num
FROM Customers a,Orders b
WHERE a.cust_id = b.cust_id
ORDER BY cust_name,order_num

# 显式内连接
SELECT cust_name,order_num
FROM Customers a
INNER JOIN Orders b
USING(cust_id)
ORDER BY cust_name,order_num

在这里插入图片描述

11.2、返回顾客名称和相关订单号以及每个订单的总价

Customers 表有字段,顾客名称:cust_name、顾客 id:cust_id

cust_idcust_name
cust10andy
cust1ben
cust2tony
cust22tom
cust221an
cust2217hex

Orders 订单信息表,含有字段,订单号:order_num、顾客 id:cust_id

order_numcust_id
a1cust10
a2cust1
a3cust2
a4cust22
a5cust221
a7cust2217

OrderItems 表有字段,商品订单号:order_num、商品数量:quantity、商品价格:item_price

order_numquantityitem_price
a1100010
a220010
a31015
a42550
a51525
a777

【问题】除了返回顾客名称和订单号,返回 Customers 表中的顾客名称(cust_name)和 Orders 表中的相关订单号(order_num),添加第三列 OrderTotal,其中包含每个订单的总价,并按顾客名称再按订单号对结果进行升序排序。

SELECT c.cust_name,o.order_num,(quantity * item_price) AS OrderTotal
FROM Customers c,Orders o,OrderItems oi
WHERE c.cust_id = o.cust_id AND o.order_num = oi.order_num
ORDER BY c.cust_name, o.order_num

或者

SELECT c.cust_name,o.order_num,SUM(quantity * item_price) AS OrderTotal
FROM Customers c,Orders o,OrderItems oi
WHERE c.cust_id = o.cust_id AND o.order_num = oi.order_num
GROUP BY c.cust_name, o.order_num
ORDER BY c.cust_name, o.order_num

在这里插入图片描述

注意,可能有小伙伴会这样写:

SELECT c.cust_name, o.order_num, SUM(quantity * item_price) AS OrderTotal
FROM Customers c,Orders o,OrderItems oi
WHERE c.cust_id = o.cust_id AND o.order_num = oi.order_num
GROUP BY c.cust_name
ORDER BY c.cust_name,o.order_num

这是错误的!只对 cust_name 进行聚类确实符合题意,但是不符合 GROUP BY 的语法。

select 语句中,如果没有 GROUP BY 语句,那么 cust_nameorder_num 会返回若干个值,而 sum(quantity * item_price) 只返回一个值,通过 group by cust_name 可以让 cust_name sum(quantity * item_price) 一一对应起来,或者说聚类,所以同样的,也要对 order_num 进行聚类。

一句话,select 中的字段要么都聚类,要么都不聚类

11.3、确定哪些订单购买了 prod_id 为 BR01 的产品(二)

OrderItems 代表订单商品信息表,prod_id 为产品 id;Orders 表代表订单表有 cust_id 代表顾客 id 和订单日期 order_date

OrderItems 表:

prod_idorder_num
BR01a0001
BR01a0002
BR02a0003
BR02a0013

Orders 表:

order_numcust_idorder_date
a0001cust102022-01-01 00:00:00
a0002cust12022-01-01 00:01:00
a0003cust12022-01-02 00:00:00
a0013cust22022-01-01 00:20:00

【问题】

编写 SQL 语句,使用子查询来确定哪些订单(在 OrderItems 中)购买了 prod_id 为 “BR01” 的产品,然后从Orders表中返回每个产品对应的顾客 ID(cust_id)和订单日期(order_date),按订购日期对结果进行升序排序。

提示:这一次使用连接和简单的等连接语法。

# 写法 1:子查询
SELECT cust_id,order_date
FROM Orders 
WHERE order_num IN (SELECT order_num
		FROM OrderItems 
		WHERE prod_id = 'BR01')
ORDER BY order_date

# 写法 2:连接表 inner join
SELECT cust_id,order_date
FROM Orders o
INNER JOIN OrderItems oi USING (order_num)
WHERE prod_id = 'BR01'
ORDER BY order_date

在这里插入图片描述

11.4、返回购买 prod_id 为 BR01 的产品的所有顾客的电子邮件(二)

有表 OrderItems 代表订单商品信息表,prod_id 为产品 id;Orders 表代表订单表有 cust_id 代表顾客 id 和订单日期 order_dateCustomers 表含有 cust_email 顾客邮件和 cust_id 顾客 id

OrderItems 表:

prod_idorder_num
BR01a0001
BR01a0002
BR02a0003
BR02a0013

Orders 表:

order_numcust_idorder_date
a0001cust102022-01-01 00:00:00
a0002cust12022-01-01 00:01:00
a0003cust12022-01-02 00:00:00
a0013cust22022-01-01 00:20:00

Customers 表代表顾客信息,cust_id 为顾客 id,cust_email 为顾客 email

cust_idcust_email
cust10cust10@cust.com
cust1cust1@cust.com
cust2cust2@cust.com

【问题】返回购买prod_id为 BR01 的产品的所有顾客的电子邮件(Customers 表中的 cust_email),结果无需排序。

提示:涉及到 SELECT 语句,最内层的从 OrderItems 表返回 order_num,中间的从 Customers 表返回 cust_id,但是必须使用 INNER JOIN 语法。

SELECT cust_email
FROM Orders o
INNER JOIN OrderItems oi USING (order_num)
INNER JOIN Customers c USING (cust_id)
WHERE prod_id = 'BR01'

在这里插入图片描述

11.5、确定最佳顾客的另一种方式(二)

OrderItems 表代表订单信息,确定最佳顾客的另一种方式是看他们花了多少钱,OrderItems 表有订单号 order_numitem_price 商品售出价格、quantity 商品数量

order_numitem_pricequantity
a110105
a211100
a21200
a421121
a5510
a2119
a775

Orders 表含有字段 order_num 订单号、cust_id顾客 id

order_numcust_id
a1cust10
a2cust1
a3cust2
a4cust22
a5cust221
a7cust2217

顾客表 Customers 有字段 cust_id 客户 id、cust_name 客户姓名

cust_idcust_name
cust10andy
cust1ben
cust2tony
cust22tom
cust221an
cust2217hex

【问题】编写 SQL 语句,返回订单总价不小于 1000 的客户名称和总额(OrderItems 表中的 order_num)。

提示:需要计算总和(item_price 乘以 quantity)。按总额对结果进行排序,请使用 INNER JOIN语法。

SELECT cust_name,SUM(item_price*quantity) AS total_price
FROM Customers c
INNER JOIN Orders o USING (cust_id)
INNER	JOIN OrderItems oi USING (order_num)
GROUP BY cust_name
HAVING total_price >= 1000
ORDER BY total_price

在这里插入图片描述

12、创建高级连接

12.1、检索每个顾客的名称和所有的订单号(一)

Customers 表代表顾客信息含有顾客 id cust_id 和 顾客名称 cust_name

cust_idcust_name
cust10andy
cust1ben
cust2tony
cust22tom
cust221an
cust2217hex

Orders 表代表订单信息含有订单号 order_num 和顾客 id cust_id

order_numcust_id
a1cust10
a2cust1
a3cust2
a4cust22
a5cust221
a7cust2217

【问题】使用 INNER JOIN 编写 SQL 语句,检索每个顾客的名称(Customers 表中的 cust_name)和所有的订单号(Orders 表中的 order_num),最后根据顾客姓名 cust_name 升序返回。

SELECT cust_name,order_num
FROM Customers 
INNER JOIN Orders 
USING (cust_id)
ORDER BY cust_name 

在这里插入图片描述

12.2、检索每个顾客的名称和所有的订单号(二)

Orders 表代表订单信息含有订单号 order_num 和顾客 id cust_id

order_numcust_id
a1cust10
a2cust1
a3cust2
a4cust22
a5cust221
a7cust2217

Customers 表代表顾客信息含有顾客 id cust_id 和 顾客名称 cust_name

cust_idcust_name
cust10andy
cust1ben
cust2tony
cust22tom
cust221an
cust2217hex
cust40ace

【问题】检索每个顾客的名称(Customers 表中的 cust_name)和所有的订单号(Orders 表中的 order_num),列出所有的顾客,即使他们没有下过订单。最后根据顾客姓名 cust_name 升序返回。

SELECT cust_name,order_num
FROM Customers 
LEFT JOIN Orders 
USING (cust_id)
ORDER BY cust_name 

在这里插入图片描述

12.3、返回产品名称和与之相关的订单号

Products 表为产品信息表含有字段prod_id产品 id、prod_name 产品名称

prod_idprod_name
a0001egg
a0002sockets
a0013coffee
a0003cola
a0023soda

OrderItems 表为订单信息表含有字段 order_num 订单号和产品 id prod_id

prod_idorder_num
a0001a105
a0002a1100
a0002a200
a0013a1121
a0003a10
a0003a19
a0003a5

【问题】使用外连接(left join、 right join、full join)联结 Products 表和 OrderItems 表,返回产品名称(prod_name)和与之相关的订单号(order_num)的列表,并按照产品名称升序排序。

SELECT prod_name,order_num
FROM  Products
LEFT JOIN  OrderItems
USING (prod_id)
ORDER BY prod_name

在这里插入图片描述

12.4、返回产品名称和每一项产品的总订单数

Products 表为产品信息表含有字段 prod_id 产品 id、prod_name 产品名称

prod_idprod_name
a0001egg
a0002sockets
a0013coffee
a0003cola
a0023soda

OrderItems 表为订单信息表含有字段 order_num 订单号和产品 id prod_id

prod_idorder_num
a0001a105
a0002a1100
a0002a200
a0013a1121
a0003a10
a0003a19
a0003a5

【问题】

使用 OUTER JOIN 联结 Products 表和 OrderItems 表,返回产品名称(prod_name)和每一项产品的总订单数(不是订单号),并按产品名称升序排序。

SELECT prod_name,COUNT(order_num) AS orders
FROM  Products
LEFT JOIN  OrderItems
USING (prod_id)
GROUP BY prod_name
ORDER BY prod_name

在这里插入图片描述

12.5、列出供应商及其可供产品的数量

Vendors 表含有 vend_id (供应商 id)

vend_id
a0002
a0013
a0003
a0010

Products表含有 vend_id(供应商 id)和 prod_id(供应产品 id)

vend_idprod_id
a0001egg
a0002prod_id_iphone
a00113prod_id_tea
a0003prod_id_vivo phone
a0010prod_id_huawei phone

【问题】列出供应商(Vendors 表中的 vend_id)及其可供产品的数量,包括没有产品的供应商。你需要使用 OUTER JOIN 和 COUNT()聚合函数来计算Products表中每种产品的数量,最后根据 vend_id 升序排序。

注意:vend_id 列会显示在多个表中,因此在每次引用它时都需要完全限定它。

SELECT vend_id,COUNT(prod_id) AS prod_id
FROM Vendors 
LEFT JOIN Products
USING (vend_id)
GROUP BY vend_id
ORDER BY vend_id

在这里插入图片描述

13、组合查询

UNION 运算符将两个或更多查询的结果组合起来,并生成一个结果集,其中包含来自 UNION 中参与查询的提取行。

UNION 基本规则:

  • 所有查询的列数和列顺序必须相同。
  • 每个查询中涉及表的列的数据类型必须相同或兼容。
  • 通常返回的列名取自第一个查询。

默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL

SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;

UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。

JOIN vs UNION`:

  • JOIN 中连接表的列可能不同,但在 UNION 中,所有查询的列数和列顺序必须相同。
  • UNION 将查询之后的行放在一起(垂直放置),但 JOIN 将查询之后的列放在一起(水平放置),即它构成一个笛卡尔积。

13.1、将两个 SELECT 语句结合起来(一)

OrderItems 包含订单产品信息,字段prod_id代表产品 id、quantity 代表产品数量

prod_idquantity
a0001105
a0002100
a0002200
a00131121
a000310
a000319
a00035
BNBG10002

【问题】将两个 SELECT 语句结合起来,以便从 OrderItems 表中检索产品 id(prod_id)和 quantity。其中,一个 SELECT 语句过滤数量为 100 的行,另一个 SELECT 语句过滤 id 以 BNBG 开头的产品,最后按产品 id 对结果进行升序排序。

SELECT prod_id,quantity
FROM OrderItems 
WHERE quantity = 100
UNION
SELECT prod_id,quantity
FROM OrderItems 
WHERE prod_id LIKE 'BNBG%' 
ORDER BY prod_id

在这里插入图片描述

13.2、将两个 SELECT 语句结合起来(二)

OrderItems 包含订单产品信息,字段 prod_id 代表产品 id、quantity 代表产品数量。

prod_idquantity
a0001105
a0002100
a0002200
a00131121
a000310
a000319
a00035
BNBG10002

【问题】将两个SELECT语句结合起来,以便从 OrderItems 表中检索产品 id(prod_id)和 quantity。其中,一个 SELECT 语句过滤数量为 100 的行,另一个 SELECT 语句过滤 id 以 BNBG 开头的产品,最后按产品 id 对结果进行升序排序。 注意:这次仅使用单个 SELECT 语句。

答案:

要求只用一条 select 语句,那就用 or 不用 union 了。

SELECT prod_id,quantity
FROM OrderItems 
WHERE quantity = 100 OR prod_id LIKE 'BNBG%' 
ORDER BY prod_id

在这里插入图片描述

13.3、组合 Products 表中的产品名称和 Customers 表中的顾客名称

Products 表含有字段 prod_name 代表产品名称

prod_name
flower
rice
ring
umbrella

Customers 表代表顾客信息,cust_name 代表顾客名称

cust_name
andy
ben
tony
tom
an
lee
hex

【问题】编写 SQL 语句,组合 Products 表中的产品名称(prod_name)和 Customers 表中的顾客名称(cust_name)并返回,然后按产品名称对结果进行升序排序。

# UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
SELECT prod_name
FROM Products
UNION
SELECT cust_name
FROM Customers
ORDER BY prod_name

在这里插入图片描述

13.4、检查 SQL 语句

Customers 含有字段 cust_name 顾客名、cust_contact 顾客联系方式、cust_state 顾客州、cust_email 顾客 email

cust_namecust_contactcust_statecust_email
cust108695192MIcust10@cust.com
cust18695193MIcust1@cust.com
cust28695194ILcust2@cust.com

【问题】修正下面错误的 SQL

SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state = 'MI'
ORDER BY cust_name;
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state = 'IL'
ORDER BY cust_name;

修正后:

SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state = 'MI'
UNION
SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state = 'IL'
ORDER BY cust_name;

使用 union 组合查询时,只能使用一条 order by 字句,他必须位于最后一条select语句之后

或者直接用 or 来做:

SELECT cust_name, cust_contact, cust_email
FROM Customers
WHERE cust_state = 'MI' or cust_state = 'IL'
ORDER BY cust_name;

好文推荐
《【SQL】SQL常见面试题总结(2)》
《【SQL】SQL常见面试题总结(3)》
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/631927.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

React 第三十七章 Scheduler 最小堆算法

在 Scheduler 中&#xff0c;使用最小堆的数据结构在对任务进行排序。 // 两个任务队列 var taskQueue: Array<Task> []; var timerQueue: Array<Task> [];push(timerQueue, newTask); // 像数组中推入一个任务 pop(timerQueue); // 从数组中弹出一个任务 time…

【漏洞复现】用友 NC portal-registerServlet JNDI注入漏洞

0x01 产品简介 用友NC是用友网络科技股份有限公司开发的一款大型企业数字化平台。它主要用于企业的财务核算、成本管理、资金管理、固定资产管理、应收应付管理等方面的工作,致力于帮助企业建立科学的财务管理体系,提高财务核算的准确性和效率。 0x02 漏洞概述 用友NC存在…

Elasticsearch 在滴滴的应用与实践

滴滴 Elasticsearch 简介 简介 Elasticsearch 是一个基于 Lucene 构建的开源、分布式、RESTful 接口的全文搜索引擎&#xff0c;其每个字段均可被索引&#xff0c;且能够横向扩展至数以百计的服务器存储以及处理 TB 级的数据&#xff0c;其可以在极短的时间内存储、搜索和分析大…

登录接口取到token,加到请求头中,通过服务器验证#Vue3

登录接口取到token&#xff0c;加到请求头中&#xff0c;通过服务器验证#Vue3 Token验证的基本流程 1.服务端收到请求&#xff0c;去验证用户名与密码 2.验证成功后&#xff0c;服务端会签发一个 Token&#xff0c;再把这个 Token 发送给客户端 3.客户端收到 Token 以后可以把它…

Linux文件系统详解

&#x1f30e;Linux文件系统 文章目录&#xff1a; Linux文件系统 简单认识磁盘 文件系统       磁盘线性结构抽象       文件系统存储方法 inode Table         inode Bitmap         Data Block         Block Bitmap         …

【漏洞复现】方正全媒体采编系统密码泄露漏洞

0x01 产品简介 方正全媒体新闻采编系统是一个面向媒体深度融合的技术平台&#xff0c;它以大数据和AI技术为支撑&#xff0c;集成了指挥中心、采集中心、编辑中心、发布中心、绩效考核中心、资料中心等多个功能&#xff0c;全面承载“策采编审发存传评”的融媒体业务流程。 0…

爱吃香蕉的珂珂

题目链接 爱吃香蕉的珂珂 题目描述 注意点 piles.length < h < 10^9如果某堆香蕉少于k根&#xff0c;将吃掉这堆的所有香蕉&#xff0c;然后这一小时内不会再吃更多的香蕉返回可以在 h 小时内吃掉所有香蕉的最小速度 k&#xff08;k 为整数&#xff09; 解答思路 二…

Find My资讯|苹果 iOS 17.5 率先执行跨平台反跟踪器标准

苹果和谷歌公司于 2023 年 5 月宣布推出“检测预期外位置追踪器”&#xff08;Detecting Unwanted Location Trackers&#xff09;行业标准&#xff0c;经过 1 年多的打磨之后&#xff0c;该标准目前已通过 iOS 17.5 部署到 iPhone 上。谷歌也将为运行 Android 6.0 或更高版本的…

【从零开始学架构 架构基础】二 架构设计的复杂度来源:高性能复杂度来源

架构设计的复杂度来源其实就是架构设计要解决的问题&#xff0c;主要有如下几个&#xff1a;高性能、高可用、可扩展、低成本、安全、规模。复杂度的关键&#xff0c;就是新旧技术之间不是完全的替代关系&#xff0c;有交叉&#xff0c;有各自的特点&#xff0c;所以才需要具体…

FestDfs快速安装和数据迁移同步。Ubuntu环境

一&#xff1a;防火墙 ufw status 二&#xff1a;下载 分别是&#xff08;环境依赖&#xff0c;网络模块依赖&#xff0c;安装包&#xff09; git clone https://github.com/happyfish100/libfastcommon.git git clone https://github.com/happyfish100/libserverframe.git …

package-lock.json导致npm install安装nyc出现超时错误

一、背景 前端项目在npm install安装依赖&#xff0c;无法下载组件nyc&#xff0c;详细报错信息&#xff1a; npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request to https://registry.npm.taobao.org/nyc/download/nyc-13.3.0.tgz?cache0&a…

析构函数详解

目录 析构函数概念特性对象的销毁顺序 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接 &#x1f412;&#x1f412;&#x1f412; 个人主页 &#x1f978;&#x1f978;&#x1f978; C语言 &#x1f43f;️&#x1f43f;️&#x1f43f;️ C语言例题 &…

开源标注工具LabelMe的使用

开源标注工具LabelMe使用Python实现&#xff0c;并使用Qt作为其图形界面&#xff0c;进行图像多边形标注。源码地址:https://github.com/labelmeai/labelme &#xff0c;最新发布版本为v5.4.1&#xff0c;它遵循GNU通用公共许可证的条款。 1.Features (1).多边形、矩形、圆形、…

Linux下mysql备份

参考文章&#xff1a; Linux实现MySQL数据库数据自动备份&#xff0c;并定期删除以前备份文件-CSDN博客文章浏览阅读7.2k次&#xff0c;点赞7次&#xff0c;收藏29次。引言在学习过程中遇到了一个问题&#xff0c;见图&#xff1a;当我进入服务器的数据库时&#xff0c;原来的…

羊大师:羊奶健康的成长伴侣

羊大师&#xff1a;羊奶健康的成长伴侣 在追求健康生活的当下&#xff0c;越来越多的人开始关注饮食的营养与健康。羊大师发现在众多天然食品中&#xff0c;羊奶以其独特的营养价值和健康益处&#xff0c;逐渐成为了人们的新宠。特别是对于正在成长发育的孩子们来说&#xff0…

客户端Web资源缓存

为了提高Web服务器的性能,其中的一种可以提高Web服务器性能的方法就是采用缓存技术。 1.缓存 1.1.什么是缓存&#xff1f; 如果某个资源的计算耗时或耗资源&#xff0c;则执行一次并存储结果。当有人随后请求该资源时&#xff0c;返回存储的结果&#xff0c;而不是再次计算。…

免费视频格式在线转换网站,推荐这5款!

在数字化时代&#xff0c;视频已成为我们日常生活和工作中不可或缺的一部分。然而&#xff0c;随着各种设备和平台的不断涌现&#xff0c;视频格式繁多&#xff0c;常常会出现不兼容的情况。为了解决这一问题&#xff0c;视频格式在线转换网站应运而生&#xff0c;成为了我们应…

【数据结构】排序(归并排序,计数排序)

一、归并排序 基本思想&#xff1a; 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide and Conquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xf…

百度百舸 AIAK-LLM 的大模型训练和推理加速实践

本文整理自 4 月 16 日的 2024 百度 Create 大会的公开课分享《百舸 AIAK-LLM&#xff1a;大模型训练和推理加速实践》。 今天要分享的主题是 AI Infra 相关的内容&#xff0c;主要内容分为四部分。 首先和大家一起讨论大模型给基础设施带来的挑战。第二部分则是向大家介绍一个…

力扣HOT100 - 32. 最长有效括号

解题思路&#xff1a; 栈 class Solution {public int longestValidParentheses(String s) {int max 0;// 也可以使用 Stack<Integer> stacknew Stack<>();但Stack是遗留类&#xff0c;不推荐Deque<Integer> stack new LinkedList<>();stack.push(…