mysql基础 Task02:基础查询与排序

SELECT
    [ALL | DISTINCT | DISTINCTROW ]
    select_expr [, select_expr] ...
    [FROM table_references
    [WHERE where_condition]
    [GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]]
    [HAVING where_condition]
    [ORDER BY {col_name | expr | position}
      [ASC | DESC], ... [WITH ROLLUP]]
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]

1. SELECT 语句基础

1.1 SELECT语句

# 语法
SELECT 列名 FROM 表名;

# 示例
mysql> SELECT DEPTNO, DNAME FROM DEPT;
+--------+------------+
| DEPTNO | DNAME      |
+--------+------------+
|     10 | ACCOUNTING |
|     20 | RESEARCH   |
|     30 | SALES      |
|     40 | OPERATIONS |
+--------+------------+

1.2 WHERE 语句

SELECT 语句通过 WHERE 子句满足查询指定条件的数据。

# 语法
SELECT 列名 FROM 表名 WHERE 条件;

# 示例
# 查询 product_type 列为 clothes 的所有商品
mysql> SELECT product_id, product_name, product_type FROM tbl_product WHERE product_type='clothes';
+------------+----------------+--------------+
| product_id | product_name   | product_type |
+------------+----------------+--------------+
| 0001       | T-shirt        | clothes      |
| 0003       | sports T-shirt | clothes      |
+------------+----------------+--------------+

# 查询销售价格大于等于1000的衣服
mysql> SELECT
    -> product_id, product_name, product_type, sale_price
    -> FROM tbl_product
    -> WHERE product_type='clothes' and sale_price>=1000;
+------------+----------------+--------------+------------+
| product_id | product_name   | product_type | sale_price |
+------------+----------------+--------------+------------+
| 0001       | T-shirt        | clothes      |       1000 |
| 0003       | sports T-shirt | clothes      |       4000 |
+------------+----------------+--------------+------------+

1.2 相关法则

  • 星号(*)代表全部列的意思。
  • SQL中可以随意使用换行符,不影响语句执行(但不可插入空行)。
  • 字符串需要使用单引号(')或者双引号(")括起来。
  • 在SELECT语句中使用DISTINCT可以删除重复行。
  • 注释
    • 单行注释:--或者#
    • 多行注释:/* */

示例

# 查询 价格在1000~4000的所有商品信息
mysql> SELECT * FROM tbl_product WHERE sale_price BETWEEN 1000 AND 4000;
+------------+----------------+--------------+------------+----------------+---------------+
| product_id | product_name   | product_type | sale_price | purchase_price | register_date |
+------------+----------------+--------------+------------+----------------+---------------+
| 0001       | T-shirt        | clothes      |       1000 |            500 | 2009-09-20    |
| 0003       | sports T-shirt | clothes      |       4000 |           2800 | NULL          |
| 0004       | kitchen knife  | kitchenware  |       3000 |           2800 | 2009-09-20    |
+------------+----------------+--------------+------------+----------------+---------------+

# 查询 商品类别
mysql> SELECT DISTINCT product_type FROM tbl_product;
+-----------------+
| product_type    |
+-----------------+
| clothes         |
| Office supplies |
| kitchenware     |
+-----------------+

2. 运算符

2.1 算术运算符

含义运算符
+、-、*、/加法、减法、乘法、除法
%,MOD
SELECT
	product_id,
	product_name,
	sale_price - purchase_price AS profit
FROM tbl_product
WHERE purchase_price IS NOT NULL;

+------------+-----------------+--------+
| product_id | product_name    | profit |
+------------+-----------------+--------+
| 0001       | T-shirt         |    500 |
| 0002       | puncher         |    180 |
| 0003       | sports T-shirt  |   1200 |
| 0004       | kitchen knife   |    200 |
| 0005       | pressure cooker |   1800 |
| 0007       | grater          |     90 |
+------------+-----------------+--------+

2.2 位运算符

NameDescription
&按位与
|按位或
^按位异或
~按位取反
<<、>>左移、右移
mysql> SELECT 3 & 2;
+-------+
| 3 & 2 |
+-------+
|     2 |
+-------+

2.3 逻辑运算符

NameDescription
>、<、=、>=、<=大于、小于、等于、大于等于、小于等于
<>、!=不等于
&&,AND逻辑与
||,OR逻辑或
NOT,!逻辑非
# 查询 价格在1000~4000的所有商品信息
SELECT * FROM tbl_product 
WHERE sale_price >= 1000 AND sale_price <= 4000;
+------------+----------------+--------------+------------+----------------+---------------+
| product_id | product_name   | product_type | sale_price | purchase_price | register_date |
+------------+----------------+--------------+------------+----------------+---------------+
| 0001       | T-shirt        | clothes      |       1000 |            500 | 2009-09-20    |
| 0003       | sports T-shirt | clothes      |       4000 |           2800 | NULL          |
| 0004       | kitchen knife  | kitchenware  |       3000 |           2800 | 2009-09-20    |
+------------+----------------+--------------+------------+----------------+---------------+

# 查询 价格不在1000~4000范围的所有商品信息
SELECT * FROM tbl_product 
WHERE NOT (sale_price >= 1000 AND sale_price <= 4000);
mysql> SELECT * FROM tbl_product
    -> WHERE NOT (sale_price >= 1000 AND sale_price <= 4000);
+------------+-----------------+-----------------+------------+----------------+---------------+
| product_id | product_name    | product_type    | sale_price | purchase_price | register_date |
+------------+-----------------+-----------------+------------+----------------+---------------+
| 0002       | puncher         | Office supplies |        500 |            320 | 2009-09-11    |
| 0005       | pressure cooker | kitchenware     |       6800 |           5000 | 2009-01-15    |
| 0006       | fork            | kitchenware     |        500 |           NULL | 2009-09-20    |
| 0007       | grater          | kitchenware     |        880 |            790 | 2008-04-28    |
| 0008       | ballpoint       | Office supplies |        100 |           NULL | 2009-11-11    |
+------------+-----------------+-----------------+------------+----------------+---------------+

含有NULL时的真值:NULL的真值结果既不为真,也不为假,因为并不知道这样一个值。那该如何表示呢?

这时真值是除真假之外的第三种值——不确定(UNKNOWN)。一般的逻辑运算并不存在这第三种值。SQL 之外的语言也基本上只使用真和假这两种真值。与通常的逻辑运算被称为二值逻辑相对,只有 SQL 中的逻辑运算被称为三值逻辑。

2.4 常用法则

  • SELECT 子句中可以使用常数或者表达式。
  • 使用逻辑运算符时一定要注意不等号和等号的位置。
  • 字符串类型的数据原则上按照字典顺序进行排序,不能与数字的大小顺序混淆。
  • 希望选取NULL记录时,需要在条件表达式中使用IS NULL运算符。希望选取不是NULL的记录时,需要在条件表达式中使用IS NOT NULL运算符。
SELECT
	product_name, sale_price, sale_price * 2 AS "sale_price x2"
FROM tbl_product;
+-----------------+------------+---------------+
| product_name    | sale_price | sale_price x2 |
+-----------------+------------+---------------+
| T-shirt         |       1000 |          2000 |
| puncher         |        500 |          1000 |
| sports T-shirt  |       4000 |          8000 |
| kitchen knife   |       3000 |          6000 |
| pressure cooker |       6800 |         13600 |
| fork            |        500 |          1000 |
| grater          |        880 |          1760 |
| ballpoint       |        100 |           200 |
+-----------------+------------+---------------+

# 选取 purchase_price 为 NULL 的记录
SELECT product_name, purchase_price
FROM tbl_product
WHERE purchase_price IS NULL;
+--------------+----------------+
| product_name | purchase_price |
+--------------+----------------+
| fork         |           NULL |
| ballpoint    |           NULL |
+--------------+----------------+

2.5 通过括号优先处理

“商品种类为办公用品”并且“登记日期是 2009 年 9 月 11 日或者 2009 年 9 月 20 日”,理想结果为“打孔器”,但当你输入以下信息时,会得到错误结果

/*
  将查询条件原封不动地写入条件表达式,会得到错误结果
  实际上条件变成了
  	(product_type = 'Office supplies' AND register_date = '2009-09-11') OR register_date = '2009-09-20';
*/
SELECT product_name, product_type, register_date
  FROM tbl_product
 WHERE product_type = 'Office supplies'
   AND register_date = '2009-09-11'
    OR register_date = '2009-09-20';
+---------------+-----------------+---------------+
| product_name  | product_type    | register_date |
+---------------+-----------------+---------------+
| T-shirt       | clothes         | 2009-09-20    |
| puncher       | Office supplies | 2009-09-11    |
| kitchen knife | kitchenware     | 2009-09-20    |
| fork          | kitchenware     | 2009-09-20    |
+---------------+-----------------+---------------+

错误的原因是 AND 运算符优先于 OR 运算符,想要优先执行OR运算,可以使用括号:

SELECT product_name, product_type, register_date
  FROM tbl_product
 WHERE product_type = 'Office supplies'
   AND (register_date = '2009-09-11' OR register_date = '2009-09-20');
+--------------+-----------------+---------------+
| product_name | product_type    | register_date |
+--------------+-----------------+---------------+
| puncher      | Office supplies | 2009-09-11    |
+--------------+-----------------+---------------+

练习题-第一部分

  1. 编写一条SQL语句,从 tbl_product 表中选取出“登记日期(register在2009年4月28日之后”的商品,查询结果要包含 product_name 和register_date 两列。

    SELECT product_name, register_date
    FROM tbl_product
    WHERE register_date > '2009-4-28';
    +---------------+---------------+
    | product_name  | register_date |
    +---------------+---------------+
    | T-shirt       | 2009-09-20    |
    | puncher       | 2009-09-11    |
    | kitchen knife | 2009-09-20    |
    | fork          | 2009-09-20    |
    | ballpoint     | 2009-11-11    |
    +---------------+---------------+
    
  2. 请说出对 product 表执行如下3条 SELECT 语句时的返回结果。

    # 1. 查询 purchase_price 为空的商品信息
    SELECT * FROM tbl_product WHERE purchase_price = NULL;
    
    # 2. 查询结果是空的
    SELECT * FROM tbl_product WHERE purchase_price <> NULL;
    # 正确写法 查询 purchase_price 不为空的商品信息
    SELECT * FROM tbl_product WHERE purchase_price IS NULL;
    
    # 3. 查询结果是空的
    # 正确写法 查询 product_name 不为空的商品信息
    SELECT * FROM tbl_product WHERE product_name IS NOT NULL;
    
  3. 代码清单2-22(2-2节)中的 SELECT 语句能够从 tbl_product 表中取出“销售单价(sale_price)比进货单价(purchase_price)高出500日元以上”的商品。请写出两条可以得到相同结果的 SELECT 语句。执行结果如下所示。

    SELECT product_name, sale_price, purchase_price
    FROM tbl_product
    WHERE sale_price - purchase_price >= 500;
    +-----------------+------------+----------------+
    | product_name    | sale_price | purchase_price |
    +-----------------+------------+----------------+
    | T-shirt         |       1000 |            500 |
    | sports T-shirt  |       4000 |           2800 |
    | pressure cooker |       6800 |           5000 |
    +-----------------+------------+----------------+
    
  4. 请写出一条 SELECT 语句,从 tbl_product 表中选取出满足“销售单价打九折之后利润高于100日元的办公用品和厨房用具”条件的记录。查询结果要包括 product_name 列、product_type 列以及销售单价打九折之后的利润(别名设定为 profit)。

    提示:销售单价打九折,可以通过saleprice列的值乘以0.9获得,利润可以通过该值减去purchase_price列的值获得。

    SELECT
    	product_name, product_type, (sale_price * 0.9 - purchase_price)  AS profit
    FROM
    	tbl_product
    WHERE
    	(sale_price * 0.9 - purchase_price) >= 100
    	AND product_type IN('Office supplies', 'kitchenware');
    +-----------------+-----------------+--------+
    | product_name    | product_type    | profit |
    +-----------------+-----------------+--------+
    | puncher         | Office supplies |  130.0 |
    | pressure cooker | kitchenware     | 1120.0 |
    +-----------------+-----------------+--------+
    

3. 对表进行聚合查询

3.1 聚合函数

SQL中用于汇总的函数叫做聚合函数(或叫统计函数、分组函数、组函数)。以下五个是最常用的聚合函数:

  • COUNT:计算表中的记录数(行数)
  • SUM:计算表中数值列中数据的合计值
  • AVG:计算表中数值列中数据的平均值
  • MAX:求出表中任意列中数据的最大值
  • MIN:求出表中任意列中数据的最小值
# 查询 sale_price 大于 1000 的商品数量
SELECT COUNT(*) FROM tbl_product WHERE sale_price > 1000;
+----------+
| COUNT(*) |
+----------+
|        3 |
+----------+

# 查询 总的 sale_price 和 总的 purchase_price
SELECT SUM(sale_price 和),  SUM(purchase_price) FROM tbl_product;
+-----------------+---------------------+
| SUM(sale_price) | SUM(purchase_price) |
+-----------------+---------------------+
|           16780 |               12210 |
+-----------------+---------------------+

# 查询 最大 sale_price、最小 sale_price、最大 purchase_price、最小 purchase_price
SELECT MAX(sale_price),  MIN(sale_price), MAX(purchase_price),  MIN(purchase_price) FROM tbl_product;
+-----------------+-----------------+---------------------+---------------------+
| MAX(sale_price) | MIN(sale_price) | MAX(purchase_price) | MIN(purchase_price) |
+-----------------+-----------------+---------------------+---------------------+
|            6800 |             100 |                5000 |                 320 |
+-----------------+-----------------+---------------------+---------------------+

# 查询 平均 sale_price 和平均 purchase_price
SELECT AVG(sale_price),  AVG(purchase_price) FROM tbl_product;
+-----------------+---------------------+
| AVG(sale_price) | AVG(purchase_price) |
+-----------------+---------------------+
|       2097.5000 |           2035.0000 |
+-----------------+---------------------+
  • 使用聚合函数删除重复值
# 计算去除重复数据后的数据行数
SELECT COUNT(DISTINCT product_type)
 FROM tbl_product;
+------------------------------+
| COUNT(DISTINCT product_type) |
+------------------------------+
|                            3 |
+------------------------------+

# 是否使用DISTINCT时的动作差异(SUM函数),因为 sale_price 有两个 500,所以去重后求和会少 500
SELECT SUM(sale_price), SUM(DISTINCT sale_price)
	FROM tbl_product;
+-----------------+--------------------------+
| SUM(sale_price) | SUM(DISTINCT sale_price) |
+-----------------+--------------------------+
|           16780 |                    16280 |
+-----------------+--------------------------+

3.2 常用法则

  • COUNT 函数的结果根据参数的不同而不同。

    • COUNT(*) :得到包含 NULL 的数据行数
    • COUNT(<列名>) :得到不包含 NULL 的数据行数。
  • 聚合函数会将 NULL 排除在外。但 COUNT(*) 例外,并不会排除 NULL 。

  • MAX / MIN 函数几乎适用于所有数据类型的列,对于字符串类型按字典顺序越往后越大。 SUM / AVG 函数只适用于数值类型的列。

  • 想要计算值的种类数量时,可以在 COUNT 函数的参数中使用 DISTINCT 。

  • 在聚合函数的参数中使用 DISTINCT,可以删除重复数据。

4. 对表进行分组

4.1 GROUP BY 语句

之前使用聚合函数都是会整个表的数据进行处理。🍰

当想将进行分组汇总时(将现有的数据按照某列来汇总统计),就需要使用 GROUP BY。

SELECT
    [ALL | DISTINCT | DISTINCTROW ]
    select_expr [, select_expr] ...
    [FROM table_references
    [WHERE where_condition]
    [GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]]
# 按照商品种类,统计数据行数
SELECT product_type, COUNT(*)
FROM tbl_product	
GROUP BY product_type;
+-----------------+----------+
| product_type    | COUNT(*) |
+-----------------+----------+
| clothes         |        2 |
| Office supplies |        2 |
| kitchenware     |        4 |
+-----------------+----------+

# 不含GROUP BY
ERROR 1140 (42000): In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'shop.tbl_product.product_type'; this is incompatible with sql_mode=only_full_group_by
聚合键中包含NULL时

将进货单价(purchase_price)作为聚合键举例:将值为 NULL 的分到一个组里面。

SELECT purchase_price, COUNT(*)
  FROM tbl_product
 GROUP BY purchase_price;
 +----------------+----------+
| purchase_price | COUNT(*) |
+----------------+----------+
|            500 |        1 |
|            320 |        1 |
|           2800 |        2 |
|           5000 |        1 |
|           NULL |        2 |
|            790 |        1 |
+----------------+----------+
GROUP BY书写位置

GROUP BY的子句书写顺序有严格要求,不按要求会导致SQL无法正常执行,目前出现过的子句顺序为:

1 SELECT → 2 FROM → 3 WHERE → 4 GROUP BY

其中前三项用于筛选数据GROUP BY对筛选出的数据进行处理

执行顺序为:1 FROM → 2 WHERE → 3 GROUP BY → 4 SELECT

WHERE子句中使用GROUP BY
SELECT purchase_price, COUNT(*)
FROM tbl_product
WHERE product_type = 'clothes'
GROUP BY purchase_price;
+----------------+----------+
| purchase_price | COUNT(*) |
+----------------+----------+
|            500 |        1 |
|           2800 |        1 |
+----------------+----------+

4.2 常见错误

在使用聚合函数及GROUP BY子句时,经常出现的错误有:

  • 在聚合函数的 SELECT 子句中写了聚合健以外的列 使用 COUNT 等聚合函数时,SELECT 子句中如果出现列名,只能是 GROUP BY 子句中指定的列名(也就是聚合键)

    SLELECT product_name
    FROM tbl_product
    GROUP BY product_type;
    
    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 'SLELECT product_name FROM tbl_product GROUP BY product_type' at line 1
    
  • 在MySQL里面GROUP BY 子句中是可以使用 SELECT 子句通过 AS 来定义的别名但是不推荐。可能是MySQL底层多了优化。🐶

    在Oracle、Hive等数据库里面GROUP BY 是不能使用别名的。因为SELECT 子句在 GROUP BY 子句后执行。

    SELECT product_type AS p_type, COUNT(*)
    FROM tbl_product
    GROUP BY p_type;
    +-----------------+----------+
    | p_type          | COUNT(*) |
    +-----------------+----------+
    | clothes         |        2 |
    | Office supplies |        2 |
    | kitchenware     |        4 |
    +-----------------+----------+
    
  • 在 WHERE 中不能使用聚合函数。

    原因是聚合函数的使用前提是结果集已经确定,而 WHERE 还处于确定结果集的过程中,所以相互矛盾会引发错误。

    如果想指定条件,可以在 SELECT,HAVING(下面马上会讲)以及 ORDER BY 子句中使用聚合函数。

5. 为聚合结果指定条件

5.1 用HAVING得到特定分组

这里用 WHERE 不可行,因为 WHERE 子句只能指定记录(行)的条件,而不能用来指定组(列)的条件(例如,“数据行数为 2 行”或者“平均值为 500”等)。

可以在 GROUP BY 后使用 HAVING 子句。

5.2 HAVING特点

HAVING 子句用于对分组进行过滤,可以使用数字聚合函数GROUP BY 中指定的列名(聚合键)

# 数字 聚合函数
SELECT product_type, COUNT(*) AS `count`
FROM tbl_product
GROUP BY product_type
HAVING `count` = 2;
+-----------------+-------+
| product_type    | count |
+-----------------+-------+
| clothes         |     2 |
| Office supplies |     2 |
+-----------------+-------+

# 错误形式(因为 product_name 不包含在 GROUP BY 聚合键中)
SELECT product_type, COUNT(*) AS `count`
FROM tbl_product
GROUP BY product_type
HAVING sale_price >= 1000;
# ERROR 1054 (42S22): Unknown column 'sale_price' in 'having clause'

6. 对查询结果进行排序

6.1 ORDER BY 子句

SQL中的执行结果是随机排列的,当需要按照特定顺序排序时,可已使用ORDER BY子句。

SELECT
    select_expr [, select_expr] ...
    [FROM table_references
    [ORDER BY {col_name | expr | position}
      [ASC | DESC], ... [WITH ROLLUP]]

默认为升序排列(ASC),降序排列为 DESC

# 按 purchase_price 升序排列
SELECT product_id, product_name, sale_price, purchase_price
FROM tbl_product
WHERE purchase_price >= 500
ORDER BY purchase_price;
+------------+-----------------+------------+----------------+
| product_id | product_name    | sale_price | purchase_price |
+------------+-----------------+------------+----------------+
| 0001       | T-shirt         |       1000 |            500 |
| 0007       | grater          |        880 |            790 |
| 0003       | sports T-shirt  |       4000 |           2800 |
| 0004       | kitchen knife   |       3000 |           2800 |
| 0005       | pressure cooker |       6800 |           5000 |
+------------+-----------------+------------+----------------+

# 按 purchase_price 升序排列,purchase_price相同时,按 sale_price 升序排列
SELECT product_id, product_name, sale_price, purchase_price
FROM tbl_product
WHERE purchase_price >= 500
ORDER BY purchase_price ASC, sale_price ASC;
+------------+-----------------+------------+----------------+
| product_id | product_name    | sale_price | purchase_price |
+------------+-----------------+------------+----------------+
| 0001       | T-shirt         |       1000 |            500 |
| 0007       | grater          |        880 |            790 |
| 0004       | kitchen knife   |       3000 |           2800 |
| 0003       | sports T-shirt  |       4000 |           2800 |
| 0005       | pressure cooker |       6800 |           5000 |
+------------+-----------------+------------+----------------+

6.2 ORDER BY 中可使用别名

前文讲 GROUP BY 中提到,GROUP BY 子句中不能使用 SELECT 子句定义的别名,但是在 ORDER BY 子句中却可以使用别名。

为什么在GROUP BY中不可以而在ORDER BY中可以呢?

这是因为SQL在使用 HAVING 子句时 SELECT 语句的执行顺序为:

1 FROM → 2 WHERE → 3 GROUP BY → 4 HAVING → 5 SELECT → 6 ORDER BY。

其中 SELECT 在 GROUP BY 后 ORDER BY 前执行的。也就是说,当在 ORDER BY中使用别名时,已经知道了 SELECT 设置的别名存在,但是在GROUP BY 中使用别名时还不知道别名的存在,所以能在 ORDER BY 中可以使用别名,但是不能在 GROUP BY中使用别名。

练习题-第二部分

  1. 请指出下述 SELECT 语句中所有的语法错误。
SELECT product_id, SUM(product_name) 
FROM tbl_product 
GROUP BY product_type 
WHERE register_date > '2009-09-01';

错误1:SUM(product_name),不能使用中文括号,SUM 对 product_name 字符类型求和没有意义。

错误2:SELECT product_id, SUM(product_name) ,SELECT 子句,只能使用聚合键,不能使用其他列名

错误3:GROUP BY product_type WHERE register_date > '2009-09-01',WHERE 子句应该在 FROM 子句后 GROUP BY 子句前。

正确写法

# 按照 商品种类 统计 注册日期在 2009-09-01 之后 的商品
SELECT product_type, COUNT(*)
FROM tbl_product
WHERE register_date > '2009-09-01'
GROUP BY product_type;
+-----------------+----------+
| product_type    | COUNT(*) |
+-----------------+----------+
| clothes         |        1 |
| Office supplies |        2 |
| kitchenware     |        2 |
+-----------------+----------+
  1. 请编写一条 SELECT 语句,求出销售单价( sale_price 列)合计值大于进货单价( purchase_price 列)合计值1.5倍的商品种类。执行结果如下所示。
product_type | sum  | sum 
-------------+------+------
clothes         | 5000 | 3300
Office supplies |  600 | 320

思路:先查出按 product_type分组,每个商品类别的总销售单价和总进货单价,然后使用having对分组结果过滤。

# 每个商品类别的总销售单价和总进货单价
SELECT product_type, SUM(sale_price) AS `sum`, SUM(purchase_price) AS `sum`
FROM tbl_product
GROUP BY product_type;
+-----------------+-------+------+
| product_type    | sum   | sum  |
+-----------------+-------+------+
| clothes         |  5000 | 3300 |
| Office supplies |   600 |  320 |
| kitchenware     | 11180 | 8590 |
+-----------------+-------+------+

# 使用having对分组结果过滤
SELECT product_type, SUM(sale_price) AS `sum`, SUM(purchase_price) AS `sum`
FROM tbl_product
GROUP BY product_type
HAVING SUM(sale_price) > SUM(purchase_price) * 1.5;
+-----------------+------+------+
| product_type    | sum  | sum  |
+-----------------+------+------+
| clothes         | 5000 | 3300 |
| Office supplies |  600 |  320 |
+-----------------+------+------+
  1. 此前我们曾经使用SELECT语句选取出了product(商品)表中的全部记录。当时我们使用了ORDERBY子句来指定排列顺序,但现在已经无法记起当时如何指定的了。请根据下列执行结果,思考ORDERBY子句的内容。
  • 发现 product_id、product_name、product_type、sale_price、purchase_price都是无序的,register_date 是降序。所以应该是首先对 register_date 进行降序排列。

  • 接下来重点关注 register_date 有相同时的值 2009-09-20 的那三行数据。发现product_id、product_name、product_type无序,sale_price 和 purchase_price都是升序的。

+------------+-----------------+-----------------+------------+----------------+---------------+
| product_id | product_name    | product_type    | sale_price | purchase_price | register_date |
+------------+-----------------+-----------------+------------+----------------+---------------+
| 0006       | fork            | kitchenware     |        500 |           NULL | 2009-09-20    |
| 0001       | T-shirt         | clothes         |       1000 |            500 | 2009-09-20    |
| 0004       | kitchen knife   | kitchenware     |       3000 |           2800 | 2009-09-20    |

😂 太菜了,对比两种情况,结果都一样,NULL值被当做最小值,排到后面了。。结果如下:

SELECT *
FROM tbl_product
ORDER BY register_date DESC, sale_price ASC;

SELECT *
FROM tbl_product
ORDER BY register_date DESC, purchase_price ASC;

+------------+-----------------+-----------------+------------+----------------+---------------+
| product_id | product_name    | product_type    | sale_price | purchase_price | register_date |
+------------+-----------------+-----------------+------------+----------------+---------------+
| 0008       | ballpoint       | Office supplies |        100 |           NULL | 2009-11-11    |
| 0006       | fork            | kitchenware     |        500 |           NULL | 2009-09-20    |
| 0001       | T-shirt         | clothes         |       1000 |            500 | 2009-09-20    |
| 0004       | kitchen knife   | kitchenware     |       3000 |           2800 | 2009-09-20    |
| 0002       | puncher         | Office supplies |        500 |            320 | 2009-09-11    |
| 0005       | pressure cooker | kitchenware     |       6800 |           5000 | 2009-01-15    |
| 0007       | grater          | kitchenware     |        880 |            790 | 2008-04-28    |
| 0003       | sports T-shirt  | clothes         |       4000 |           2800 | NULL          |
+------------+-----------------+-----------------+------------+----------------+---------------+

参考文献

  1. https://github.com/datawhalechina/wonderful-sql
  2. https://dev.mysql.com/doc/refman/8.0/en/select.html
  3. https://www.runoob.com/mysql/mysql-select-query.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值