MySQL——select_type详解——六月十五

select_type:查询的类型。

  • SIMPLE:简单 SELECT,不需要使用 UNION 操作或子查询。
  • PRIMARY:如果查询包含子查询,最外层的 SELECT 被标记为 PRIMARY。
  • UNION:UNION 操作中第二个或后面的 SELECT 语句。
  • SUBQUERY:子查询中的第一个 SELECT。
  • DERIVED:派生表的 SELECT 子查询。

可以用一种类比的方式来解释这些查询类型:

假设你是一位厨师,正在准备一道复杂的菜肴。你需要从不同的食材和调料中选择,并将它们组合在一起以制作最终的菜品。

  • SIMPLE(简单)查询就像你从一个食材库中直接选择所需的食材,不需要进行任何额外的操作。

  • PRIMARY(主要)查询是指你在制作菜品时需要使用到子菜品。你可能会先制作子菜品,然后将它们组合在一起形成最终的菜品。在查询中,最外层的 SELECT 语句就扮演了主要查询的角色。

  • UNION(并集)查询是指你在制作菜品时需要将两个或多个独立的子菜品合并在一起。例如,你可能会制作一个蔬菜沙拉和一个水果沙拉,然后将它们合并成一个水果蔬菜沙拉。在查询中,UNION 操作中的第二个或后续的 SELECT 语句就扮演了并集查询的角色。

  • SUBQUERY(子查询)是指你在制作菜品时需要使用到其他菜品的某些组成部分。例如,你可能需要先制作一种特殊的酱汁,然后将其用于主菜中。在查询中,子查询就像是你先制作某个组成部分,然后将其嵌入到主查询中的一部分。

  • DERIVED(派生)查询是指你在制作菜品时需要使用到已经准备好的一些中间产品。例如,你可能需要制作一个蛋糕,但需要使用到已经制作好的奶油作为其中的一层。在查询中,派生查询就像是你从已经准备好的中间产品中提取所需的部分。

这种类比帮助理解不同类型的查询在查询过程中的作用和关系,就像在制作菜品时选择和组合不同的食材和调料一样。

提供一些示例,以更具体地说明各种查询类型的用途。

  1. SIMPLE(简单)查询示例:

    SELECT * 
    FROM customers;
    

    这是一个简单的 SELECT 查询,它从名为 “customers” 的表中选择所有的记录。

  2. PRIMARY(主要)查询示例:

    SELECT * 
    FROM orders 
    WHERE customer_id IN (SELECT id FROM customers WHERE country = 'USA');
    

    这个查询中,外层的 SELECT 语句是主要查询,它使用了一个子查询来获取符合条件的客户 ID,然后根据这些客户 ID 查询相关的订单信息。
    当我们具体考虑一个示例时,假设我们有两个表:orders 表和 customers 表。

orders 表结构:

order_idcustomer_idorder_date
110012023-06-01
210022023-06-02
310032023-06-03
410012023-06-04
510042023-06-05

customers 表结构:

customer_idnamecountry
1001JohnUSA
1002EmmaUK
1003MikeUSA
1004SarahCanada

现在,我们可以使用以下查询来获取在美国的客户所下的所有订单:

SELECT * 
FROM orders 
WHERE customer_id IN (SELECT customer_id FROM customers WHERE country = 'USA');

这个查询的执行步骤如下:

  1. 子查询 (SELECT customer_id FROM customers WHERE country = 'USA') 将返回在美国的客户的 customer_id 值,即 10011003

  2. 外部查询 SELECT * FROM orders WHERE customer_id IN (...) 将在 orders 表中查找具有这些 customer_id 值的订单。

查询结果将是在美国的客户所下的所有订单:

order_idcustomer_idorder_date
110012023-06-01
310032023-06-03
410012023-06-04

这样,我们就通过使用 customer_id IN (SELECT ...) 条件,成功地筛选出了在美国的客户所下的订单。

  1. UNION(并集)查询示例:
    SELECT product_name 
    FROM products 
    WHERE category = 'Fruits'
    UNION
    SELECT product_name 
    FROM products 
    WHERE category = 'Vegetables';
    
    这个查询使用 UNION 操作将两个独立的 SELECT 语句的结果合并在一起,获取属于水果或蔬菜类别的产品名称。
    我很抱歉,在之前的回答中有误导性的陈述。实际上,上述查询未显示如何消除重复项。如果查询结果中存在重复的产品名称,它们将全部显示出来。

假设我们有以下产品表:

products 表结构:

product_idproduct_namecategory
1AppleFruits
2BananaFruits
3CarrotVegetables
4TomatoVegetables
5AppleFruits

现在,我们将使用以下查询来获取属于水果或蔬菜类别的产品名称,并消除重复项:

SELECT product_name 
FROM products 
WHERE category = 'Fruits'
UNION DISTINCT
SELECT product_name 
FROM products 
WHERE category = 'Vegetables';

这个查询的执行步骤如下:

  1. 第一个查询 SELECT product_name FROM products WHERE category = 'Fruits' 选择了类别为 “Fruits” 的产品名称。这将返回 “Apple”、“Banana” 和 “Apple”。

  2. 第二个查询 SELECT product_name FROM products WHERE category = 'Vegetables' 选择了类别为 “Vegetables” 的产品名称。这将返回 “Carrot” 和 “Tomato”。

  3. UNION DISTINCT 操作将两个查询结果合并在一起,并自动去除重复的产品名称。

最终的查询结果将是属于水果或蔬菜类别的产品名称,并消除重复项:

product_name
Apple
Banana
Carrot
Tomato

请注意,现在结果集中只有一个 “Apple”,即使在原始数据中有两个相同的产品名称。通过使用 UNION DISTINCT,我们成功地消除了重复项,确保了每个产品名称只出现一次。

  1. SUBQUERY(子查询)示例:
    SELECT * 
    FROM employees 
    WHERE department_id = (SELECT id FROM departments WHERE name = 'HR');
    
    这个查询中,子查询首先获取部门名称为 “HR” 的部门 ID,然后外层的 SELECT 语句根据该部门 ID 获取相应的员工信息。
    假设我们有两个表:employees 表和 departments 表,用于存储员工和部门的信息。

employees 表结构:

employee_idemployee_namedepartment_id
1John1
2Emma2
3Mike1
4Sarah3
5David2

departments 表结构:

department_iddepartment_name
1HR
2Sales
3IT

现在,我们可以使用以下查询来获取部门名称为 “HR” 的所有员工信息:

SELECT * 
FROM employees 
WHERE department_id = 
(SELECT department_id FROM departments WHERE department_name = 'HR');

这个查询的执行步骤如下:

  1. 子查询 (SELECT department_id FROM departments WHERE department_name = 'HR') 将返回部门名称为 “HR” 的部门ID,即 1

  2. 外部查询 SELECT * FROM employees WHERE department_id = (...) 将在 employees 表中查找部门ID为 1 的员工。

查询结果将是部门名称为 “HR” 的所有员工信息:

employee_idemployee_namedepartment_id
1John1
3Mike1

这样,我们就通过使用子查询来获取部门名称为 “HR” 的部门ID,并将其用作外部查询的条件,成功地筛选出了部门为 “HR” 的所有员工信息。

  1. DERIVED(派生)查询示例:
    SELECT product_name, price 
    FROM (SELECT * FROM products 
    WHERE category = 'Bakery') AS bakery_products;
    
    这个查询中,派生查询创建了一个临时表 bakery_products,它包含了所有属于 “Bakery” 类别的产品。然后外层的 SELECT 语句从这个临时表中选择产品名称和价格。

假设我们有一个名为 products 的表,用于存储各种产品的信息。

products 表结构:

product_idproduct_namecategoryprice
1BreadBakery2.99
2CakeBakery9.99
3CookieSnacks1.49
4MuffinBakery1.99
5DonutBakery0.99

现在,我们可以使用以下查询来选择类别为 “Bakery” 的产品的名称和价格:

SELECT product_name, price 
FROM (SELECT * FROM products WHERE category = 'Bakery') AS bakery_products;

这个查询的执行步骤如下:

  1. 子查询 (SELECT * FROM products WHERE category = 'Bakery') AS bakery_products 选择了类别为 “Bakery” 的所有产品。

  2. 外部查询 SELECT product_name, price FROM (...) 在子查询返回的结果上进行查询,选择了产品名称和价格列。

最终的查询结果将是类别为 “Bakery” 的产品的名称和价格:

product_nameprice
Bread2.99
Cake9.99
Muffin1.99
Donut0.99

通过将子查询的结果作为临时表命名为 bakery_products,然后在外部查询中选择所需的列,我们成功地筛选出了类别为 “Bakery” 的产品的名称和价格。

如果没有在子查询后面使用 AS bakery_products 进行别名定义,查询仍然可以正常执行,但在后续的查询中无法引用子查询结果作为临时表。

以下是没有使用别名的示例查询:

SELECT product_name, price 
FROM (SELECT * FROM products WHERE category = 'Bakery');

该查询的执行步骤如下:

  1. 子查询 (SELECT * FROM products WHERE category = 'Bakery') 选择了类别为 “Bakery” 的所有产品。

  2. 外部查询 SELECT product_name, price FROM (...) 在子查询返回的结果上进行查询,选择了产品名称和价格列。

虽然查询本身没有错误,但由于没有为子查询结果指定别名,后续无法直接引用该子查询的结果。在这种情况下,如果我们尝试在外部查询或其他查询中引用该子查询的结果,将会出现语法错误。

因此,使用别名可以将子查询结果命名为一个临时表,使我们可以在后续的查询中引用该临时表。这种方式有助于提高查询的可读性和灵活性。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值