小熊奶糖(BearCandy)
小熊奶糖(BearCandy)
发布于 2024-04-23 / 12 阅读
0
0

MySQL 高级查询 聚合函数|逻辑运算符

MySQL聚合函数|逻辑运算符

MySQL聚合函数和逻辑运算符都是在处理数据库查询时非常重要的工具。聚合函数用于对一组数据进行统计计算,生成单个汇总值,而逻辑运算符则用于对布尔表达式进行判断,以确定查询条件的逻辑关系。当需要在查询中同时使用聚合函数和逻辑运算符时,理解它们的混合使用方式以及运算顺序至关重要。以下是对这些概念的详细解释,以及运算顺序的详解:

MySQL 聚合函数

MySQL 支持多种聚合函数,包括但不限于:

  1. COUNT():返回指定列中非NULL值的行数。
  2. SUM():计算指定列中所有数值的总和。
  3. AVG():计算指定列中所有数值的平均值。
  4. MAX():返回指定列中的最大值。
  5. MIN():返回指定列中的最小值。

例如:

SELECT COUNT(*), AVG(salary), MAX(sales), MIN(price)
FROM employees;

上述查询将分别计算 employees表中的总行数、员工薪资的平均值、最大销售额和最低价格。

MySQL 逻辑运算符

MySQL 中的逻辑运算符主要包括:

  1. NOT!:逻辑非,否定其后的表达式。如果表达式为真(1),则结果为假(0);若为假(0)或 NULL,则结果为真(1)。
  2. AND&&:逻辑与,当两边的表达式都为真时结果才为真,否则为假。
  3. OR或者||:逻辑或,只要两边的表达式中有一个为真,结果就为真;只有两边都为假时结果才为假。

例如:

SELECT * FROM orders
WHERE status = 'completed' AND payment_received = 1 OR customer_id = 100;

此查询将选择状态为“completed”,已收到付款或客户ID为100的所有订单。

逻辑运算符混合使用及运算顺序

在使用逻辑运算符时,遵循特定的运算优先级和结合性规则,这对于正确构建复杂的查询条件至关重要。根据MySQL的运算符优先级,逻辑运算符的优先级从高到低排列如下:

  1. NOT(逻辑非)
  2. AND(逻辑与)
  3. OR(逻辑或)

这意味着:

  • NOT 最先被计算。
  • 同一优先级的运算符(如多个 AND 或多个 OR)按照从左到右的顺序(即结合性)进行计算。
  • 当不同优先级的运算符混合使用时,高优先级运算符先于低优先级运算符执行。

例如,对于以下查询:

SELECT * FROM products
WHERE price > 100 AND (category = 'Electronics' OR brand = 'Apple');

运算顺序如下:

  1. 首先,评估括号内的条件 (category = 'Electronics' OR brand = 'Apple')
  2. 其次,将得到的结果与 price > 100 使用 AND 运算符进行组合。

如果希望改变默认的运算顺序,可以使用括号明确指定优先级,如上述示例中的括号确保了 OR运算先于外部的 AND运算进行。

当遇到不带括号的复合条件表达式 price > 100 AND category = 'Electronics' OR brand = 'Apple',要理解其实际运算顺序,需要依据MySQL的逻辑运算符优先级规则。由于没有括号来明确指定优先级,根据优先级从高到低的顺序(NOT -> AND -> OR),运算过程如下:

  1. 优先级规则

    • AND 的优先级高于 OR
    • 没有括号的情况下,从左到右依次计算。
  2. 实际运算步骤

    首先,由于 AND 的优先级较高,会先计算左侧的 price > 100category = 'Electronics' 之间的逻辑关系:

    (price > 100 AND category = 'Electronics')
    

    然后,这个结果作为一个整体与右侧的 brand = 'Apple' 通过 OR 运算符进行组合:

    (price > 100 AND category = 'Electronics') OR brand = 'Apple'
    

    这意味着查询将返回以下三类记录:

    • 价格大于100且类别为“Electronics”的产品。
    • 品牌为“Apple”的产品(不论价格和类别如何)。

    注意:此处的运算顺序可能会导致非预期结果,因为 AND 优先级高,它将首先对 price > 100category = 'Electronics' 两部分进行联合筛选,然后再将这一结果与其他满足 brand = 'Apple' 的记录合并。这可能会包括一些不符合原意的记录,比如价格低于100但品牌为“Apple”的产品。

    如果意图筛选出同时满足以下条件之一的产品:

    • 价格大于100且类别为“Electronics”;
    • 或者品牌为“Apple”。

    那么正确的写法应该使用括号来确保 OR 运算的优先级:

    price > 100 AND (category = 'Electronics' OR brand = 'Apple')
    

    或者:

    (price > 100 AND category = 'Electronics') OR (price > 100 AND brand = 'Apple')
    

    这样才能准确地表达“价格大于100且类别为‘Electronics’或者品牌为‘Apple’”的条件。

综上所述,不带括号的 price > 100 AND category = 'Electronics' OR brand = 'Apple' 表达式的实际运算逻辑是先计算 price > 100category = 'Electronics' 的逻辑与,然后将结果与 brand = 'Apple' 进行逻辑或。为了避免混淆和确保查询语句表达意图的准确性,建议在涉及多个逻辑运算符时使用括号来明确指定优先级。

结合聚合函数与逻辑运算符

聚合函数通常在 GROUP BY 子句之后使用,对分组后的数据进行统计计算。当需要基于聚合结果应用逻辑判断时,可以在 HAVING 子句中使用逻辑运算符,因为 WHERE 子句无法直接作用于聚合函数。

例如:

SELECT department, COUNT(*) AS employee_count
FROM employees
GROUP BY department
HAVING COUNT(*) > 10; -- 应用逻辑运算符过滤出员工数量超过10人的部门

在这个查询中,COUNT(*) 是聚合函数,计算每个部门的员工数量。然后在 HAVING 子句中使用 > 逻辑运算符和常量值10,筛选出员工数量大于10的部门结果。

总结来说,MySQL 中聚合函数与逻辑运算符的混合使用涉及到运算优先级、结合性规则以及在适当位置(如 WHEREHAVING 子句)应用逻辑判断。理解并正确运用这些规则有助于编写精确、高效的 SQL 查询。

实训:

Enter password: ****
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.44-log MySQL Community Server (GPL)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
mysql>
mysql>
mysql> create databse if not exists testDB;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'datab
se if not exists testDB' at line 1
mysql> create database if not exists testDB;
Query OK, 1 row affected (0.03 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| bms                |
| db_com             |
| db_test1           |
| lb_db              |
| lb_db1             |
| mysql              |
| performance_schema |
| sys                |
| test1              |
| test3              |
| test5              |
| testdb             |
+--------------------+
13 rows in set (0.02 sec)

mysql> use testdb
Database changed
mysql> select database();
+------------+
| database() |
+------------+
| testdb     |
+------------+
1 row in set (0.00 sec)

mysql> create table user
    -> (id int auto_increment primary key,name varchar(30) not null unique,sex v
archar(30),score float default 0);
Query OK, 0 rows affected (0.17 sec)

mysql> show full columns form user\G;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'form
user' at line 1
ERROR:
No query specified

mysql> show full columns from user\G;
*************************** 1. row ***************************
     Field: id
      Type: int(11)
 Collation: NULL
      Null: NO
       Key: PRI
   Default: NULL
     Extra: auto_increment
Privileges: select,insert,update,references
   Comment:
*************************** 2. row ***************************
     Field: name
      Type: varchar(30)
 Collation: latin1_swedish_ci
      Null: NO
       Key: UNI
   Default: NULL
     Extra:
Privileges: select,insert,update,references
   Comment:
*************************** 3. row ***************************
     Field: sex
      Type: varchar(30)
 Collation: latin1_swedish_ci
      Null: YES
       Key:
   Default: NULL
     Extra:
Privileges: select,insert,update,references
   Comment:
*************************** 4. row ***************************
     Field: score
      Type: float
 Collation: NULL
      Null: YES
       Key:
   Default: 0
     Extra:
Privileges: select,insert,update,references
   Comment:
4 rows in set (0.01 sec)

ERROR:
No query specified

mysql> insert into user (name,sex,score) values
    -> ('小明','男',55),
    -> ('小红','女',72),
    -> ('小张','男',88),
    -> ('张三','男',80),
    -> ('李四','女',40),
    -> ('李梅','女',60),
    -> ('小美','男',99);
ERROR 1366 (HY000): Incorrect string value: '\xE5\xB0\x8F\xE6\x98\x8E' for colum
n 'name' at row 1
mysql> alter table user convert to character set utf8mb4;
Query OK, 0 rows affected (0.26 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> insert into user (name,sex,score) values
    -> ('小明','男',55),
    -> ('小红','女',72),
    -> ('小张','男',88),
    -> ('张三','男',80),
    -> ('李四','女',40),
    -> ('李梅','女',60),
    -> ('小美','男',99);
Query OK, 7 rows affected (0.02 sec)
Records: 7  Duplicates: 0  Warnings: 0

mysql> select * from user;
+----+--------+------+-------+
| id | name   | sex  | score |
+----+--------+------+-------+
|  1 | 小明   | 男   |    55 |
|  2 | 小红   | 女   |    72 |
|  3 | 小张   | 男   |    88 |
|  4 | 张三   | 男   |    80 |
|  5 | 李四   | 女   |    40 |
|  6 | 李梅   | 女   |    60 |
|  7 | 小美   | 男   |    99 |
+----+--------+------+-------+
7 rows in set (0.00 sec)

mysql> select * from name like '%张%';
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'like
'%张%'' at line 1
mysql> select * from user name like '%张%';
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'like
'%张%'' at line 1
mysql> select * from user where name like '%张%';
+----+--------+------+-------+
| id | name   | sex  | score |
+----+--------+------+-------+
|  3 | 小张   | 男   |    88 |
|  4 | 张三   | 男   |    80 |
+----+--------+------+-------+
2 rows in set (0.04 sec)

mysql> select * from user where name like '%四%';
+----+--------+------+-------+
| id | name   | sex  | score |
+----+--------+------+-------+
|  5 | 李四   | 女   |    40 |
+----+--------+------+-------+
1 row in set (0.00 sec)

mysql> select score from user where name='张三';
+-------+
| score |
+-------+
|    80 |
+-------+
1 row in set (0.01 sec)

mysql> select * from user where id=1 or id=2;
+----+--------+------+-------+
| id | name   | sex  | score |
+----+--------+------+-------+
|  1 | 小明   | 男   |    55 |
|  2 | 小红   | 女   |    72 |
+----+--------+------+-------+
2 rows in set (0.01 sec)

mysql> select * from user where score between 80 and 90;
+----+--------+------+-------+
| id | name   | sex  | score |
+----+--------+------+-------+
|  3 | 小张   | 男   |    88 |
|  4 | 张三   | 男   |    80 |
+----+--------+------+-------+
2 rows in set (0.00 sec)

mysql> select * from user where score>90;
+----+--------+------+-------+
| id | name   | sex  | score |
+----+--------+------+-------+
|  7 | 小美   | 男   |    99 |
+----+--------+------+-------+
1 row in set (0.01 sec)

mysql> select id,name,sex,avg(score) from user;
ERROR 1140 (42000): In aggregated query without GROUP BY, expression #1 of SELEC
T list contains nonaggregated column 'testdb.user.id'; this is incompatible with
 sql_mode=only_full_group_by
mysql> select avg(score) from user;
+-------------------+
| avg(score)        |
+-------------------+
| 70.57142857142857 |
+-------------------+
1 row in set (0.01 sec)

mysql>

MySQL高级查询

MySQL第四章节单表查询.pptx
https://www.alipan.com/s/3F31d12DNok
点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。


评论