mysql 学习

本文来自于《sql必知必会》
所需要的文件教程连接 本站其他的小伙伴

第一课 了解sql

数据库基础

什么是数据库

数据库(database) 保存有组织的数据的容器(通常是一个文 件或一组文件)。

表(table) 某种特定类型数据的结构化清单。

存储在表中的数据是一种类型的数据或一个 清单。决不应该将顾客的清单与订单的清单存储在同一个数据库表中。这 样做将使以后的检索和访问很困难。应该创建两个表,每个清单一个表。

表名的唯一性取决于多个因素,如数据库名和表名等的 结合。这表示,虽然在相同数据库中不能两次使用相同的表名, 但在不同的数据库中却可以使用相同的表名。

模式schema

模式(schema) 关于数据库和表的布局及特性的信息。

是模式还是数据库? 有时,模式用作数据库的同义词。遗憾 的是,模式的含义通常在上下文中并不是很清晰。

列和数据类型

列(column) 表中的一个字段。所有表都是由一个或多个列组 成的。

分解数据 正确地将数据分解为多个列极为重要。

数据类型(datatype) 所容许的数据的类型。每个表列都有相 应的数据类型,它限制(或容许)该列中存储的数据。

行(row) 表中的一个记录。

主键

主键(primary key)一一列(或一组列),其值能够唯一区分表 中每个行

唯一标识表中每行的这个列(或这组列)称为主键。主键用来表示 一个特定的行。没有主键,更新或删除表中特定行很困难,因为没有安 全的方法保证只涉及相关的行

应该总是定义主键 虽然并不总是都需要主键,但大多数数据 库设计人员都应保证他们创建的每个表具有一个主键,以便于 以后的数据操纵和管理

表中的任何列都可以作为主键,只要它满足以下条件:

  •  任意两行都不具有相同的主键值;

  •  每个行都必须具有一个主键值(主键列不允许NULL值)

主键的最好习惯 除MySQL强制实施的规则外,应该坚持的 几个普遍认可的最好习惯为:

  •  不更新主键列中的值;
  •  不重用主键列的值;
  •  不在主键列中使用可能会更改的值。(例如,如果使用一个 名字作为主键以标识某个供应商,当该供应商合并和更改其 名字时,必须更改这个主键。

什么是sql

SQL(发音为字母S-Q-L或sequel)是结构化查询语言(Structured Query Language)的缩写。SQL是一种专门用来与数据库通信的语言

SQL有如下的优点。

  •  SQL不是某个特定数据库供应商专有的语言。几乎所有重要的 DBMS都支持SQL,所以,学习此语言使你几乎能与所有数据库 打交道。
  •  SQL简单易学。它的语句全都是由描述性很强的英语单词组成, 而且这些单词的数目不多。
  •  SQL尽管看上去很简单,但它实际上是一种强有力的语言,灵活 使用其语言元素,可以进行非常复杂和高级的数据库操作。

第二课 MySQL简述

什么是MySQL

数据的所有存储、 检索、管理和处理实际上是由数据库软件——DBMS(数据库管理系统) 完成的。MySQL是一种DBMS,即它是一种数据库软件。

为什么有那么多的公司和开发人员使用MySQL?

  •  成本——MySQL是开放源代码的,一般可以免费使用(甚至可以 免费修改)。
  •  性能——MySQL执行很快(非常快)。
  •  可信赖——某些非常重要和声望很高的公司、站点使用MySQL, 这些公司和站点都用MySQL来处理自己的重要数据。
  •  简单——MySQL很容易安装和使用。

客户机—服务器软件

DBMS可分为两类:一类为基于共享文件系统的DBMS,另一类为基 于客户机—服务器的DBMS。

前者(包括诸如Microsoft Access和FileMaker)用于桌面用途,通常不用于高端或更关键的应用。

MySQL、Oracle以及Microsoft SQL Server等数据库是基于客户机—服 务器的数据库。客户机—服务器应用分为两个不同的部分。服务器部分是 负责所有数据访问和处理的一个软件。这个软件运行在称为数据库服务 器的计算机上

第三课 检索数据

select语句

SQL语句是由简单的英语单词构成的。这些单词称 为关键字,每个SQL语句都是由一个或多个关键字构成的。大概,最经常 使用的SQL语句就是SELECT语句了。它的用途是从一个或多个表中检索 信息

关键字

作为 sql 组成部分的保留字。和其他语言一样关键字不能用作表或列名字。

检索单个列

select prod_name from products;
#结构相当简单,从英文单词的语句就可以看出来从哪里选择。
+----------------+
| prod_name      |
+----------------+
| .5 ton anvil   |
| 1 ton anvil    |
| 2 ton anvil    |
| Detonator      |
| Bird seed      |
| Carrots        |
| Fuses          |
| JetPack 1000   |
| JetPack 2000   |
| Oil can        |
| Safe           |
| Sling          |
| TNT (1 stick)  |
| TNT (5 sticks) |
+----------------+

当然也包括了相应的显示了多少行数据,以及花了多长时间

14 rows in set (0.00 sec)

当然上述数据可能没有排序,输出可能每个人也不一定相同

结束SQL语句 多条SQL语句必须以分号(;)分隔。MySQL 如同多数DBMS一样,不需要在单条SQL语句后加分号。但特 定的DBMS可能必须在单条SQL语句后加上分号。当然,如果 愿意可以总是加上分号。事实上,即使不一定需要,但加上 分号肯定没有坏处。如果你使用的是mysql命令行,必须加上 分号来结束SQL语句

MySQL没有大小写的区分

许多SQL开发人员喜欢对所有SQL关键字使用大写,而对所有 列和表名使用小写,这样做使代码更易于阅读和调试

选择好自己的习惯

空格,和大多数其他语言一样空格通常也会被忽略掉

SQL 语句可以在一行上给出,也可以分成许多行。多数SQL开发人 员认为将SQL语句分成多行更容易阅读和调试。

mysql> select prod_name
    -> from Products;
+----------------+
| prod_name      |
+----------------+
| .5 ton anvil   |
| 1 ton anvil    |
| 2 ton anvil    |
| Detonator      |
| Bird seed      |
| Carrots        |
| Fuses          |
| JetPack 1000   |
| JetPack 2000   |
| Oil can        |
| Safe           |
| Sling          |
| TNT (1 stick)  |
| TNT (5 sticks) |
+----------------+
14 rows in set (0.00 sec)



mysql> select prod_name from Products;
+----------------+
| prod_name      |
+----------------+
| .5 ton anvil   |
| 1 ton anvil    |
| 2 ton anvil    |
| Detonator      |
| Bird seed      |
| Carrots        |
| Fuses          |
| JetPack 1000   |
| JetPack 2000   |
| Oil can        |
| Safe           |
| Sling          |
| TNT (1 stick)  |
| TNT (5 sticks) |
+----------------+
14 rows in set (0.00 sec)

mysql> select
    -> prod_name
    -> from
    -> Products;
+----------------+
| prod_name      |
+----------------+
| .5 ton anvil   |
| 1 ton anvil    |
| 2 ton anvil    |
| Detonator      |
| Bird seed      |
| Carrots        |
| Fuses          |
| JetPack 1000   |
| JetPack 2000   |
| Oil can        |
| Safe           |
| Sling          |
| TNT (1 stick)  |
| TNT (5 sticks) |
+----------------+
14 rows in set (0.00 sec)


## 由此上述三种表述都是一样的效果

检索多个列

要想从一个表中检索多个列,使用相同的SELECT语句。唯一的不同 是必须在SELECT关键字后给出多个列名,列名之间必须以逗号分隔。

mysql> select prod_id prod_name,prod_price
    -> from Products;
+-----------+------------+
| prod_name | prod_price |
+-----------+------------+
| ANV01     |       5.99 |
| ANV02     |       9.99 |
| ANV03     |      14.99 |
| DTNTR     |      13.00 |
| FB        |      10.00 |
| FC        |       2.50 |
| FU1       |       3.42 |
| JP1000    |      35.00 |
| JP2000    |      55.00 |
| OL1       |       8.99 |
| SAFE      |      50.00 |
| SLING     |       4.49 |
| TNT1      |       2.50 |
| TNT2      |      10.00 |
+-----------+------------+
14 rows in set (0.00 sec)

# 在这个例子中,指定了3个列名,列名之间用逗号分隔。

检索所有列

mysql> select * from Products;
+---------+---------+----------------+------------+----------------------------------------------------------------+
| prod_id | vend_id | prod_name      | prod_price | prod_desc
                                             |
+---------+---------+----------------+------------+----------------------------------------------------------------+
| ANV01   |    1001 | .5 ton anvil   |       5.99 | .5 ton anvil, black, complete with handy hook                  |
| ANV02   |    1001 | 1 ton anvil    |       9.99 | 1 ton anvil, black, complete with handy hook and carrying case |
| ANV03   |    1001 | 2 ton anvil    |      14.99 | 2 ton anvil, black, complete with handy hook and carrying case |
| DTNTR   |    1003 | Detonator      |      13.00 | Detonator (plunger powered), fuses not included                |
| FB      |    1003 | Bird seed      |      10.00 | Large bag (suitable for road runners)                          |
| FC      |    1003 | Carrots        |       2.50 | Carrots (rabbit hunting season only)                           |
| FU1     |    1002 | Fuses          |       3.42 | 1 dozen, extra long                                            |
| JP1000  |    1005 | JetPack 1000   |      35.00 | JetPack 1000, intended for single use                          |
| JP2000  |    1005 | JetPack 2000   |      55.00 | JetPack 2000, multi-use                                        |
| OL1     |    1002 | Oil can        |       8.99 | Oil can, red
                                             |
| SAFE    |    1003 | Safe           |      50.00 | Safe with combination lock                                     |
| SLING   |    1003 | Sling          |       4.49 | Sling, one size fits all                                       |
| TNT1    |    1003 | TNT (1 stick)  |       2.50 | TNT, red, single stick                                         |
| TNT2    |    1003 | TNT (5 sticks) |      10.00 | TNT, red, pack of 10 sticks                                    |
+---------+---------+----------------+------------+----------------------------------------------------------------+

检索不同的值

mysql> select vend_id from Products;
+---------+
| vend_id |
+---------+
|    1001 |
|    1001 |
|    1001 |
|    1002 |
|    1002 |
|    1003 |
|    1003 |
|    1003 |
|    1003 |
|    1003 |
|    1003 |
|    1003 |
|    1005 |
|    1005 |
+---------+
14 rows in set (0.00 sec)

#不加限制就会产生重复数据(尽管并非无用),但是某些时候我们需要排除哪些重复


mysql> select distinct vend_id
    -> from Products;
+---------+
| vend_id |
+---------+
|    1001 |
|    1002 |
|    1003 |
|    1005 |
+---------+
4 row# s in set (0.00 sec)
# distinct 显著的明显的缺失的


mysql> select distinct vend_id,prod_price from Products;
+---------+------------+
| vend_id | prod_price |
+---------+------------+
|    1001 |       5.99 |
|    1001 |       9.99 |
|    1001 |      14.99 |
|    1003 |      13.00 |
|    1003 |      10.00 |
|    1003 |       2.50 |
|    1002 |       3.42 |
|    1005 |      35.00 |
|    1005 |      55.00 |
|    1002 |       8.99 |
|    1003 |      50.00 |
|    1003 |       4.49 |
+---------+------------+
12 rows in set (0.01 sec)
# 两个组合效果

mysql> select vend_id,prod_price from Products;
+---------+------------+
| vend_id | prod_price |
+---------+------------+
|    1001 |       5.99 |
|    1001 |       9.99 |
|    1001 |      14.99 |
|    1003 |      13.00 |
|    1003 |      10.00 |
|    1003 |       2.50 |
|    1002 |       3.42 |
|    1005 |      35.00 |
|    1005 |      55.00 |
|    1002 |       8.99 |
|    1003 |      50.00 |
|    1003 |       4.49 |
|    1003 |       2.50 |
|    1003 |      10.00 |
+---------+------------+
14 rows in set (0.00 sec)
# 两个还是有显著不同的,

限制结果

MYSQL的关键字是limit,SQL server的关键字是top。

这里学的是mysql所以没有用sql server

mysql> select prod_name from Products limit 5;
+--------------+
| prod_name    |
+--------------+
| .5 ton anvil |
| 1 ton anvil  |
| 2 ton anvil  |
| Detonator    |
| Bird seed    |
+--------------+
5 rows in set (0.00 sec)
## 这里是前5行

mysql> select prod_name from Products limit 5 offset 5;
+--------------+
| prod_name    |
+--------------+
| Carrots      |
| Fuses        |
| JetPack 1000 |
| JetPack 2000 |
| Oil can      |
+--------------+
5 rows in set (0.00 sec)
#这里是从第五行开始读5行,和其他语言一样都是从0开始计数


使用注释

随着数据的增长和数据库的庞大,sql的语句边长,复杂度也会变大,所以增加一些注释行会减少自己的维护成本。

select prod_name from products; -- 这是注释

在 MySQL 中,有两种方式可以添加注释:

  1. 单行注释:使用 --# 开始一行文字,直到行尾都将被视为注释。例如:

    SELECT * FROM table_name; -- 这是一条注释
    
  2. 多行注释:使用 /* */ 将一段文字包裹起来作为注释。例如:

    /*
    这是一个多行注释
    可以在这里写很多内容
    */
    

注释可以用于在 SQL 查询中解释代码的作用或者添加说明,但不会对查询结果产生任何影响。


  1. 编写SQL语句,从Customers表中检索所有的ID(cust_id)。
SELECT cust_id
FROM Customers;
  1. OrderItems表包含了所有已订购的产品(有些已被订购多次)。编写SQL语句,检索并列出已订购产品(prod_id)的清单(不用列每个订单,只列出不同产品的清单)。
SELECT DISTINCT prod_id
FROM OrderItems;
  1. 编写SQL语句,检索Customers表中所有的列,再编写另外的SELECT语句,仅检索顾客的ID。使用注释,注释掉一条SELECT语句,以便运行另一条SELECT语句。(当然,要测试这两个语句。)
SELECT *
# SELECT cust_id
FROM Customers;

排序检索数据

第三课(补)排序数据

检索出的数据并不是以纯粹的随机顺序显示的。如果不排 序,数据一般将以它在底层表中出现的顺序显示。这可以是数据最初添加到表中的顺序。但是,如果数据后来进行过更新或删除,则此顺 序将会受到MySQL重用回收存储空间的影响。因此,如果不明确控 制的话,不能(也不应该)依赖该排序顺序。关系数据库设计理论认 为,如果不明确规定排序顺序,则不应该假定检索出的数据的顺序有 意义

子句:SQL语句由子句构成,有些子句是必需的,而 有的是可选的。一个子句通常由一个关键字和所提供的数据组成。

mysql> select prod_name from products order by prod_name;
+----------------+
| prod_name      |
+----------------+
| .5 ton anvil   |
| 1 ton anvil    |
| 2 ton anvil    |
| Bird seed      |
| Carrots        |
| Detonator      |
| Fuses          |
| JetPack 1000   |
| JetPack 2000   |
| Oil can        |
| Safe           |
| Sling          |
| TNT (1 stick)  |
| TNT (5 sticks) |
+----------------+
14 rows in set (0.00 sec)

按多个列排序

经常需要按不止一个列进行数据排序。为了按多个列排序,只要指定列名,列名之间用逗号分开即可(就 像选择多个列时所做的那样)

mysql> select prod_id,prod_price,prod_name
    -> from products
    -> order by prod_price,prod_name;
+---------+------------+----------------+
| prod_id | prod_price | prod_name      |
+---------+------------+----------------+
| FC      |       2.50 | Carrots        |
| TNT1    |       2.50 | TNT (1 stick)  |
| FU1     |       3.42 | Fuses          |
| SLING   |       4.49 | Sling          |
| ANV01   |       5.99 | .5 ton anvil   |
| OL1     |       8.99 | Oil can        |
| ANV02   |       9.99 | 1 ton anvil    |
| FB      |      10.00 | Bird seed      |
| TNT2    |      10.00 | TNT (5 sticks) |
| DTNTR   |      13.00 | Detonator      |
| ANV03   |      14.99 | 2 ton anvil    |
| JP1000  |      35.00 | JetPack 1000   |
| SAFE    |      50.00 | Safe           |
| JP2000  |      55.00 | JetPack 2000   |
+---------+------------+----------------+
14 rows in set (0.00 sec)

order by 根据后面的顺序排序。

按列位置排序

select prod_id, prod_price,prod_name from products;
+---------+------------+----------------+
| prod_id | prod_price | prod_name      |
+---------+------------+----------------+
| ANV01   |       5.99 | .5 ton anvil   |
| ANV02   |       9.99 | 1 ton anvil    |
| ANV03   |      14.99 | 2 ton anvil    |
| DTNTR   |      13.00 | Detonator      |
| FB      |      10.00 | Bird seed      |
| FC      |       2.50 | Carrots        |
| FU1     |       3.42 | Fuses          |
| JP1000  |      35.00 | JetPack 1000   |
| JP2000  |      55.00 | JetPack 2000   |
| OL1     |       8.99 | Oil can        |
| SAFE    |      50.00 | Safe           |
| SLING   |       4.49 | Sling          |
| TNT1    |       2.50 | TNT (1 stick)  |
| TNT2    |      10.00 | TNT (5 sticks) |
+---------+------------+----------------+
14 rows in set (0.00 sec)

# 有上图知道是第2 3列
mysql> select prod_id, prod_price,prod_name
    -> from products
    -> order by 2,3;
+---------+------------+----------------+
| prod_id | prod_price | prod_name      |
+---------+------------+----------------+
| FC      |       2.50 | Carrots        |
| TNT1    |       2.50 | TNT (1 stick)  |
| FU1     |       3.42 | Fuses          |
| SLING   |       4.49 | Sling          |
| ANV01   |       5.99 | .5 ton anvil   |
| OL1     |       8.99 | Oil can        |
| ANV02   |       9.99 | 1 ton anvil    |
| FB      |      10.00 | Bird seed      |
| TNT2    |      10.00 | TNT (5 sticks) |
| DTNTR   |      13.00 | Detonator      |
| ANV03   |      14.99 | 2 ton anvil    |
| JP1000  |      35.00 | JetPack 1000   |
| SAFE    |      50.00 | Safe           |
| JP2000  |      55.00 | JetPack 2000   |
+---------+------------+----------------+
14 rows in set (0.00 sec)

指定排序方向

数据排序不限于升序排序(从A到Z)。这只是默认的排序顺序,还可 以使用ORDER BY子句以降序(从Z到A)顺序排序。为了进行降序排序, 必须指定DESC关键字。

mysql> select prod_id,prod_price,prod_name
    -> from products
    -> order by prod_price desc;
+---------+------------+----------------+
| prod_id | prod_price | prod_name      |
+---------+------------+----------------+
| JP2000  |      55.00 | JetPack 2000   |
| SAFE    |      50.00 | Safe           |
| JP1000  |      35.00 | JetPack 1000   |
| ANV03   |      14.99 | 2 ton anvil    |
| DTNTR   |      13.00 | Detonator      |
| FB      |      10.00 | Bird seed      |
| TNT2    |      10.00 | TNT (5 sticks) |
| ANV02   |       9.99 | 1 ton anvil    |
| OL1     |       8.99 | Oil can        |
| ANV01   |       5.99 | .5 ton anvil   |
| SLING   |       4.49 | Sling          |
| FU1     |       3.42 | Fuses          |
| FC      |       2.50 | Carrots        |
| TNT1    |       2.50 | TNT (1 stick)  |
+---------+------------+----------------+
14 rows in set (0.00 sec)

mysql> select prod_id,prod_price,prod_name
    -> from products
    -> order by prod_price desc,prod_name;
+---------+------------+----------------+
| prod_id | prod_price | prod_name      |
+---------+------------+----------------+
| JP2000  |      55.00 | JetPack 2000   |
| SAFE    |      50.00 | Safe           |
| JP1000  |      35.00 | JetPack 1000   |
| ANV03   |      14.99 | 2 ton anvil    |
| DTNTR   |      13.00 | Detonator      |
| FB      |      10.00 | Bird seed      |
| TNT2    |      10.00 | TNT (5 sticks) |
| ANV02   |       9.99 | 1 ton anvil    |
| OL1     |       8.99 | Oil can        |
| ANV01   |       5.99 | .5 ton anvil   |
| SLING   |       4.49 | Sling          |
| FU1     |       3.42 | Fuses          |
| FC      |       2.50 | Carrots        |
| TNT1    |       2.50 | TNT (1 stick)  |
+---------+------------+----------------+
14 rows in set (0.00 sec)

DESC关键字只应用到直接位于其前面的列名。在上例中,只对 prod_price列指定DESC,对prod_name列不指定。因此, prod_price列以降序排序,而prod_name列(在每个价格内)仍然按标准 的升序排

在多个列上降序排序 如果想在多个列上进行降序排序,必须 对每个列指定DESC关键字。

区分大小写和排序顺序 在对文本性的数据进行排序时,A与 a相同吗?a位于B之前还是位于Z之后?这些问题不是理论问 题,其答案取决于数据库如何设置。

在字典(dictionary)排序顺序中,A被视为与a相同,这是MySQL (和大多数数据库管理系统)的默认行为。但是,许多数据库 管理员能够在需要时改变这种行为(如果你的数据库包含大量 外语字符,可能必须这样做)

-- prod_price DESC保证行是按照由最昂贵到最便宜检索的,而LIMIT 1告诉MySQL仅返回一行。
mysql> select prod_price
    -> from products
    -> order by prod_price desc
    -> limit 1;
+------------+
| prod_price |
+------------+
|      55.00 |
+------------+
1 row in set (0.00 sec)

1.编写SQL语句,从Customers中检索所有的顾客名称(cust_names),并按从Z到A的顺序显示结果。

mysql> SELECT cust_name
    -> FROM Customers
    -> ORDER BY cust_name DESC;
+----------------+
| cust_name      |
+----------------+
| Yosemite Place |
| Wascals        |
| Mouse House    |
| E Fudd         |
| Coyote Inc.    |
+----------------+
5 rows in set (0.00 sec)

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

SELECT cust_id, order_num
FROM Orders
ORDER BY cust_id, order_date DESC;

--------------------
mysql> SELECT cust_id, order_num
    -> FROM Orders
    -> ORDER BY cust_id, order_date DESC;
+---------+-----------+
| cust_id | order_num |
+---------+-----------+
|   10001 |     20009 |
|   10001 |     20005 |
|   10003 |     20006 |
|   10004 |     20007 |
|   10005 |     20008 |
+---------+-----------+
5 rows in set (0.00 sec)

3.显然,我们的虚拟商店更喜欢出售比较贵的物品,而且这类物品有很多。编写SQL语句,显示OrderItems表中的数量和价格(item_price),并按数量由多到少、价格由高到低排序。

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

---------------------------------------
mysql> select quantity,item_price
    -> from orderItems
    -> order by quantity desc,item_price desc;
+----------+------------+
| quantity | item_price |
+----------+------------+
|      100 |      10.00 |
|       50 |       2.50 |
|       10 |       5.99 |
|        5 |      10.00 |
|        3 |       9.99 |
|        1 |      55.00 |
|        1 |      14.99 |
|        1 |      10.00 |
|        1 |      10.00 |
|        1 |       8.99 |
|        1 |       4.49 |
+----------+------------+
11 rows in set (0.00 sec)

4.下面的SQL语句有问题吗?(尝试在不运行的情况下指出。)

  SELECT vend_name,
  FROM Vendors
  ORDER vend_name DESC;
  
#多了个逗号。

第四课 过滤数据

使用where子句

数据库表一般包含大量的数据,很少需要检索表中所有行。通常只 会根据特定操作或报告的需要提取表数据的子集。只检索所需数据需要 指定搜索条件(search criteria),搜索条件也称为过滤条件(filter condition)。

	mysql> select prod_name, prod_price
    -> from products
    -> where prod_price = 2.5;
+---------------+------------+
| prod_name     | prod_price |
+---------------+------------+
| Carrots       |       2.50 |
| TNT (1 stick) |       2.50 |
+---------------+------------+
2 rows in set (0.00 sec)

SQL过滤与应用过滤 数据也可以在应用层过滤。为此目 的,SQL的SELECT语句为客户机应用检索出超过实际所需的 数据,然后客户机代码对返回数据进行循环,以提取出需要 的行

WHERE子句的位置 在同时使用ORDER BY和WHERE子句时,应 该让ORDER BY位于WHERE之后,否则将会产生错误.

where 子句操作符

操作符描述
=等于
!= 或 <>不等于
<小于
<=小于等于
>大于
>=大于等于
BETWEEN在指定范围内
LIKE匹配模式
IN在指定值列表中
IS NULL为空值
IS NOT NULL不为空值

检查单个值

mysql> select prod_name,prod_price
    -> from products
    -> where prod_price <10;
+---------------+------------+
| prod_name     | prod_price |
+---------------+------------+
| .5 ton anvil  |       5.99 |
| 1 ton anvil   |       9.99 |
| Carrots       |       2.50 |
| Fuses         |       3.42 |
| Oil can       |       8.99 |
| Sling         |       4.49 |
| TNT (1 stick) |       2.50 |
+---------------+------------+
7 rows in set (0.00 sec)

+++++++++++++++++++++++++++++++++++

mysql> select prod_name,prod_price
    -> from products
    -> where prod_price <= 10;
+----------------+------------+
| prod_name      | prod_price |
+----------------+------------+
| .5 ton anvil   |       5.99 |
| 1 ton anvil    |       9.99 |
| Bird seed      |      10.00 |
| Carrots        |       2.50 |
| Fuses          |       3.42 |
| Oil can        |       8.99 |
| Sling          |       4.49 |
| TNT (1 stick)  |       2.50 |
| TNT (5 sticks) |      10.00 |
+----------------+------------+
9 rows in set (0.00 sec)

不匹配检查

mysql> select vend_id ,prod_name
    -> from products
    -> where vend_id <> 1003;
+---------+--------------+
| vend_id | prod_name    |
+---------+--------------+
|    1001 | .5 ton anvil |
|    1001 | 1 ton anvil  |
|    1001 | 2 ton anvil  |
|    1002 | Fuses        |
|    1002 | Oil can      |
|    1005 | JetPack 1000 |
|    1005 | JetPack 2000 |
+---------+--------------+
7 rows in set (0.01 sec)
mysql> select vend_id ,prod_name
    -> from products
    -> where vend_id != 1003;
+---------+--------------+
| vend_id | prod_name    |
+---------+--------------+
|    1001 | .5 ton anvil |
|    1001 | 1 ton anvil  |
|    1001 | 2 ton anvil  |
|    1002 | Fuses        |
|    1002 | Oil can      |
|    1005 | JetPack 1000 |
|    1005 | JetPack 2000 |
+---------+--------------+
7 rows in set (0.01 sec)

范围值检查

mysql> select prod_name,prod_price
    -> from products
    -> where prod_price between 5 and 10;
+----------------+------------+
| prod_name      | prod_price |
+----------------+------------+
| .5 ton anvil   |       5.99 |
| 1 ton anvil    |       9.99 |
| Bird seed      |      10.00 |
| Oil can        |       8.99 |
| TNT (5 sticks) |      10.00 |
+----------------+------------+
5 rows in set (0.00 sec)

在使用BETWEEN时,必须指定两个值 ——所需范围的低端值和高端值。这两个值必须用AND关键字 分隔。BETWEEN匹配范围中所有的值,包括指定的开始值和结束值。

空值检查

在创建表时,表设计人员可以指定其中的列是否可以不包含值。在 一个列不包含值时,称其为包含空值NULL。

NULL 无值(no value),它与字段包含0、空字符串或仅仅包含 空格不同

mysql> select cust_name
    -> from customers
    -> where cust_email is null;


+-------------+
| cust_name   |
+-------------+
| Mouse House |
| E Fudd      |
+-------------+
2 rows in set (0.00 sec)

NULL与不匹配 在通过过滤选择出不具有特定值的行时,你 可能希望返回具有NULL值的行。但是,不行。因为未知具有 特殊的含义,数据库不知道它们是否匹配,所以在匹配过滤 或不匹配过滤时不返回它们。 因此,在过滤数据时,一定要验证返回数据中确实给出了被 过滤列具有NULL的行。


1.编写SQL语句,从Products表中检索产品ID(prod_id)和产品名称(prod_name),只返回价格为9.49美元的产品。

mysql> SELECT prod_id, prod_name
    -> FROM Products
    -> WHERE prod_price = 9.49;
Empty set (0.00 sec)

2.编写SQL语句,从Products表中检索产品ID(prod_id)和产品名称(prod_name),只返回价格为9美元或更高的产品。

mysql> SELECT prod_id, prod_name
    -> FROM Products
    -> WHERE prod_price >= 9;
+---------+----------------+
| prod_id | prod_name      |
+---------+----------------+
| ANV02   | 1 ton anvil    |
| ANV03   | 2 ton anvil    |
| DTNTR   | Detonator      |
| FB      | Bird seed      |
| JP1000  | JetPack 1000   |
| JP2000  | JetPack 2000   |
| SAFE    | Safe           |
| TNT2    | TNT (5 sticks) |
+---------+----------------+
8 rows in set (0.00 sec)

3.结合第3课和第4课编写SQL语句,从OrderItems表中检索出所有不同订单号(order_num),其中包含100个或更多的产品。

mysql> SELECT DISTINCT order_num
    -> FROM OrderItems
    -> WHERE quantity >=100;
+-----------+
| order_num |
+-----------+
|     20007 |
+-----------+
1 row in set (0.00 sec)

4.编写SQL语句,返回Products表中所有价格在3美元到6美元之间的产品的名称(prod_name)和价格(prod_price),然后按价格对结果进行排序。(本题有多种解决方案,我们在下一课再讨论,不过你可以使用目前已学的知识来解决它。)

mysql> SELECT prod_name, prod_price
    -> FROM products
    -> WHERE prod_price BETWEEN 3 AND 6
    -> ORDER BY prod_price;
+--------------+------------+
| prod_name    | prod_price |
+--------------+------------+
| Fuses        |       3.42 |
| Sling        |       4.49 |
| .5 ton anvil |       5.99 |
+--------------+------------+
3 rows in set (0.00 sec)

第五课 数据过滤

组合where子句

and操作符

为了进行更强的过滤控制,MySQL允许给出多个WHERE子句。这些子 句可以两种方式使用:以AND子句的方式或OR子句的方式使用。

mysql> select prod_id,prod_price,prod_name
    -> from products
    -> where vend_id = 1003 and prod_price <=10;
+---------+------------+----------------+
| prod_id | prod_price | prod_name      |
+---------+------------+----------------+
| FB      |      10.00 | Bird seed      |
| FC      |       2.50 | Carrots        |
| SLING   |       4.49 | Sling          |
| TNT1    |       2.50 | TNT (1 stick)  |
| TNT2    |      10.00 | TNT (5 sticks) |
+---------+------------+----------------+
5 rows in set (0.00 sec)

or操作符

mysql> select prod_name ,prod_price
    -> from products
    -> where vend_id =1002 or vend_id =1003;
+----------------+------------+
| prod_name      | prod_price |
+----------------+------------+
| Fuses          |       3.42 |
| Oil can        |       8.99 |
| Detonator      |      13.00 |
| Bird seed      |      10.00 |
| Carrots        |       2.50 |
| Safe           |      50.00 |
| Sling          |       4.49 |
| TNT (1 stick)  |       2.50 |
| TNT (5 sticks) |      10.00 |
+----------------+------------+
9 rows in set (0.00 sec)

计算次序

WHERE可包含任意数目的AND和OR操作符。允许两者结合以进行复杂 和高级的过滤

mysql> select prod_name,prod_price
    -> from products
    -> where prod_id = 1002 or vend_id = 1003 and prod_price >=10;
+----------------+------------+
| prod_name      | prod_price |
+----------------+------------+
| Detonator      |      13.00 |
| Bird seed      |      10.00 |
| Safe           |      50.00 |
| TNT (5 sticks) |      10.00 |
+----------------+------------+
4 rows in set, 14 warnings (0.00 sec)

由于AND在计算次序中优先级更高,操作 符被错误地组合了

mysql> select prod_name,prod_price
    -> from products
    -> where (prod_id = 1002 or vend_id =1003)and prod_price >=10;
+----------------+------------+
| prod_name      | prod_price |
+----------------+------------+
| Detonator      |      13.00 |
| Bird seed      |      10.00 |
| Safe           |      50.00 |
| TNT (5 sticks) |      10.00 |
+----------------+------------+
4 rows in set, 14 warnings (0.00 sec)
# 这里可以看出优先级的差距

在WHERE子句中使用圆括号 任何时候使用具有AND和OR操作 符的WHERE子句,都应该使用圆括号明确地分组操作符。不要 过分依赖默认计算次序,即使它确实是你想要的东西也是如 此。使用圆括号没有什么坏处,它能消除歧义

in操作符

圆括号在WHERE子句中还有另外一种用法。IN操作符用来指定条件范 围,范围中的每个条件都可以进行匹配。IN取合法值的由逗号分隔的清 单,全都括在圆括号中。

mysql> select prod_name,prod_price
    -> from products
    -> where vend_id in (1002,1003)
    -> order by prod_name;
+----------------+------------+
| prod_name      | prod_price |
+----------------+------------+
| Bird seed      |      10.00 |
| Carrots        |       2.50 |
| Detonator      |      13.00 |
| Fuses          |       3.42 |
| Oil can        |       8.99 |
| Safe           |      50.00 |
| Sling          |       4.49 |
| TNT (1 stick)  |       2.50 |
| TNT (5 sticks) |      10.00 |
+----------------+------------+
9 rows in set (0.00 sec)
--下面实现的效果和上面的一样
mysql> select prod_name ,prod_price
    -> from products
    -> where vend_id = 1002 or 1003
    -> order by prod_name;
+----------------+------------+
| prod_name      | prod_price |
+----------------+------------+
| .5 ton anvil   |       5.99 |
| 1 ton anvil    |       9.99 |
| 2 ton anvil    |      14.99 |
| Bird seed      |      10.00 |
| Carrots        |       2.50 |
| Detonator      |      13.00 |
| Fuses          |       3.42 |
| JetPack 1000   |      35.00 |
| JetPack 2000   |      55.00 |
| Oil can        |       8.99 |
| Safe           |      50.00 |
| Sling          |       4.49 |
| TNT (1 stick)  |       2.50 |
| TNT (5 sticks) |      10.00 |
+----------------+------------+
14 rows in set (0.00 sec)

为什么要使用IN操作符?其优点具体如下。

  •  在使用长的合法选项清单时,IN操作符的语法更清楚且更直观。
  •  在使用IN时,计算的次序更容易管理(因为使用的操作符更少)。
  •  IN操作符一般比OR操作符清单执行更快。
  •  IN的最大优点是可以包含其他SELECT语句,使得能够更动态地建 立WHERE子句。第14章将对此进行详细介绍

not的加入

mysql> select prod_name ,prod_price
    -> from products
    -> where vend_id not in (1002,1003)
    -> order by prod_name;
+--------------+------------+
| prod_name    | prod_price |
+--------------+------------+
| .5 ton anvil |       5.99 |
| 1 ton anvil  |       9.99 |
| 2 ton anvil  |      14.99 |
| JetPack 1000 |      35.00 |
| JetPack 2000 |      55.00 |
+--------------+------------+
5 rows in set (0.00 sec)

1.编写SQL语句,从Vendors表中检索供应商名称(vend_name),仅返回加利福尼亚州的供应商(这需要按国家[USA]和州[CA]进行过滤,没准其他国家也存在一个加利福尼亚州)。提示:过滤器需要匹配字符串。

mysql> SELECT vend_name
    -> FROM Vendors
    -> WHERE vend_country = 'USA' AND vend_state = 'CA';
+-----------+
| vend_name |
+-----------+
| ACME      |
+-----------+
1 row in set (0.00 sec)

2.编写SQL语句,查找所有至少订购了总量100个的BR01、BR02或BR03的订单。你需要返回OrderItems表的订单号(order_num)、产品ID(prod_id)和数量,并按产品ID和数量进行过滤。提示:根据编写过滤器的方式,可能需要特别注意求值顺序。

mysql> SELECT order_num, prod_id, quantity
    -> FROM OrderItems
    -> WHERE prod_id IN ('BR01','BR02','BR03')
    ->  AND quantity >=100;
Empty set (0.00 sec)

3.现在,我们回顾上一课的挑战题。编写SQL语句,返回所有价格在3美元到6美元之间的产品的名称(prod_name)和价格(prod_price)。使用AND,然后按价格对结果进行排序。

mysql> SELECT prod_name, prod_price
    -> FROM products
    -> WHERE prod_price >= 3 AND prod_price <= 6
    -> ORDER BY prod_price;
+--------------+------------+
| prod_name    | prod_price |
+--------------+------------+
| Fuses        |       3.42 |
| Sling        |       4.49 |
| .5 ton anvil |       5.99 |
+--------------+------------+
3 rows in set (0.00 sec)

4.下面的SQL语句有问题吗?(尝试在不运行的情况下指出。)

  SELECT vend_name
  FROM Vendors
  ORDER BY vend_name
  WHERE vend_country = 'USA' AND vend_state = 'CA';
  
#   排序(Sorting)是最后进行的操作,必须在使用 ORDER BY 子句之前使用 WHERE 子句。

第六课 通配符进行过滤

like操作符

前面介绍的所有操作符都是针对已知值进行过滤的。不管是匹配一 个还是多个值,测试大于还是小于已知值,或者检查某个范围的值,共 同点是过滤中使用的值都是已知的。但是,这种过滤方法并不是任何时 候都好用。

通配符(wildcard) 用来匹配值的一部分的特殊字符。

搜索模式(search pattern)① 由字面值、通配符或两者组合构 成的搜索条件。

通配符本身实际是SQL的WHERE子句中有特殊含义的字符,SQL支持几 种通配符

谓词 操作符何时不是操作符?答案是在它作为谓词

百分号(%)通配符

mysql> select prod_id , prod_name
    -> from products
    -> where prod_name like 'jet%';
+---------+--------------+
| prod_id | prod_name    |
+---------+--------------+
| JP1000  | JetPack 1000 |
| JP2000  | JetPack 2000 |
+---------+--------------+
2 rows in set (0.01 sec)

通配符可在搜索模式中任意位置使用,并且可以使用多个通配符。 下面的例子使用两个通配符,它们位于模式的两端

mysql> select prod_id ,prod_name
    -> from products
    -> where prod_name like '%anvil%'
    -> ;
+---------+--------------+
| prod_id | prod_name    |
+---------+--------------+
| ANV01   | .5 ton anvil |
| ANV02   | 1 ton anvil  |
| ANV03   | 2 ton anvil  |
+---------+--------------+
3 rows in set (0.00 sec)

通配符也可以出现在搜索模式中间,虽然不常用

mysql> select prod_name
    -> from products
    -> where prod_name like 's%e';
+-----------+
| prod_name |
+-----------+
| Safe      |
+-----------+
1 row in set (0.00 sec)

下划线_通配符

但下划 线只匹配单个字符而不是多个字符

mysql> select prod_id ,prod_name
    -> from products
    -> where prod_name like '_ ton anvil'
    -> ;
+---------+-------------+
| prod_id | prod_name   |
+---------+-------------+
| ANV02   | 1 ton anvil |
| ANV03   | 2 ton anvil |
+---------+-------------+
2 rows in set (0.00 sec)

WHERE子句中的搜索模式给出了后面跟有文本的两个通配 符。结果只显示匹配搜索模式的行:第一行中下划线匹配1, 第二行中匹配2。.5 ton anvil产品没有匹配,因为搜索模式要求匹配两 个通配符而不是一个。

mysql> select prod_id,prod_name
    -> from products
    -> where prod_name like '% ton anvil';
+---------+--------------+
| prod_id | prod_name    |
+---------+--------------+
| ANV01   | .5 ton anvil |
| ANV02   | 1 ton anvil  |
| ANV03   | 2 ton anvil  |
+---------+--------------+
3 rows in set (0.00 sec)

使用通配符的技巧

  • 不要过度使用通配符。如果其他操作符能达到相同的目的,应该 使用其他操作符。
  •  在确实需要使用通配符时,除非绝对有必要,否则不要把它们用 在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起 来是最慢的。
  •  仔细注意通配符的位置。如果放错地方,可能不会返回想要的数据。

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

mysql> SELECT prod_name, prod_desc
    -> FROM Products
    -> WHERE prod_desc LIKE '%toy%';
Empty set (0.00 sec)

2.反过来再来一次。编写SQL语句,从Products表中检索产品名称(prod_name)和描述(prod_desc),仅返回描述中未出现toy一词的产品。这次,按产品名称对结果进行排序。

mysql> select prod_name,prod_desc
    -> from products
    -> where not prod_desc like '%toy%'
    -> order by prod_name;
+----------------+----------------------------------------------------------------+
| prod_name      | prod_desc
            |
+----------------+----------------------------------------------------------------+
| .5 ton anvil   | .5 ton anvil, black, complete with handy hook                  |
| 1 ton anvil    | 1 ton anvil, black, complete with handy hook and carrying case |
| 2 ton anvil    | 2 ton anvil, black, complete with handy hook and carrying case |
| Bird seed      | Large bag (suitable for road runners)
            |
| Carrots        | Carrots (rabbit hunting season only)
            |
| Detonator      | Detonator (plunger powered), fuses not included                |
| Fuses          | 1 dozen, extra long
            |
| JetPack 1000   | JetPack 1000, intended for single use
            |
| JetPack 2000   | JetPack 2000, multi-use
            |
| Oil can        | Oil can, red
            |
| Safe           | Safe with combination lock
            |
| Sling          | Sling, one size fits all
            |
| TNT (1 stick)  | TNT, red, single stick
            |
| TNT (5 sticks) | TNT, red, pack of 10 sticks
            |
+----------------+----------------------------------------------------------------+
14 rows in set (0.00 sec)

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

mysql> SELECT prod_name, prod_desc
    -> FROM Products
    -> WHERE prod_desc LIKE '%toy%' AND prod_desc LIKE '%carrots%';
Empty set (0.00 sec)

4.来个比较棘手的。我没有特别向你展示这个语法,而是想看看你根据目前已学的知识是否可以找到答案。编写SQL语句,从Products表中检索产品名称(prod_name)和描述(prod_desc),仅返回在描述中以先后顺序同时出现toy和carrots的产品。提示:只需要用带有三个%符号的LIKE即可。

mysql> select prod_name, prod_desc
    -> from products
    -> where prod_desc like '%toy%carrots%';
Empty set (0.00 sec)	

使用正则表达式进行搜索(补)

正则表达式用正则表达式语言来建立,正则表达式语言是用来完成 刚讨论的所有工作以及更多工作的一种特殊语言。

mysql> select prod_name
    -> from products
    -> where prod_name regexp '1000'
    -> order by prod_name;
+--------------+
| prod_name    |
+--------------+
| JetPack 1000 |
+--------------+
1 row in set (0.00 sec)

除关键字LIKE被REGEXP替代外,这条语句看上去非常像使用 LIKE的语句。它告诉MySQL:REGEXP后所跟的东西作 为正则表达式(与文字正文1000匹配的一个正则表达式)处理。

mysql> select prod_name
    -> from products
    -> where prod_name regexp '.000'
    -> order by prod_name;
+--------------+
| prod_name    |
+--------------+
| JetPack 1000 |
| JetPack 2000 |
+--------------+
2 rows in set (0.01 sec)

正则表达式提供了一种强大且灵活的方式来处理文本数据,尤其在需要进行模式匹配、搜索、替换等操作时非常有用。虽然正则表达式可能在某些情况下性能不如其他方法(例如简单的字符串比较),但它在处理复杂模式和大量数据时仍然是一种非常有效的工具。

正则表达式的优势包括:

  1. 灵活性和表达力:正则表达式可以描述各种复杂的文本模式,包括字符、字符串、位置、数量等,比简单的字符串比较更具表达力。
  2. 通用性:正则表达式是一种通用的文本处理工具,可以用于多种编程语言和操作系统。
  3. 批量处理:正则表达式可以一次性处理大量文本数据,提高处理效率。
  4. 标准化:正则表达式是一种标准化的文本处理方法,在不同环境下具有一致的语法和行为。

进行or匹配

mysql> select prod_name
    -> from products
    -> where prod_name regexp '1000|2000'
    -> order by prod_name;
+--------------+
| prod_name    |
+--------------+
| JetPack 1000 |
| JetPack 2000 |
+--------------+
2 rows in set (0.00 sec)

匹配几个字符之一

匹配任何单一字符。但是,如果你只想匹配特定的字符,怎么办? 可通过指定一组用[和]括起来的字符来完成

mysql> select prod_name
    -> from products
    -> where prod_name regexp '[123] Ton'
    -> order by prod_name;
+-------------+
| prod_name   |
+-------------+
| 1 ton anvil |
| 2 ton anvil |
+-------------+
2 rows in set (0.01 sec)

,[]是另一种形式的OR语句。事实上,正则表达式[123]Ton 为[1|2|3]Ton的缩写,也可以使用后者。但是,需要用[]来定义OR语句 查找什么。

mysql> select prod_name
    -> from products
    -> where prod_name regexp '1|2|3 Ton'
    -> order by prod_name;
+---------------+
| prod_name     |
+---------------+
| 1 ton anvil   |
| 2 ton anvil   |
| JetPack 1000  |
| JetPack 2000  |
| TNT (1 stick) |
+---------------+
5 rows in set (0.00 sec)

这并不是期望的输出。两个要求的行被检索出来,但还检索出 了另外3行。之所以这样是由于MySQL假定你的意思是’1’或 ‘2’或’3 ton’。除非把字符|括在一个集合中,否则它将应用于整个串。

字符集合也可以被否定,即,它们将匹配除指定字符外的任何东西。 为否定一个字符集,在集合的开始处放置一个^即可。因此,尽管[123] 匹配字符1、2或3,但 [ ^123 ] 却匹配除这些字符外的任何东西

匹配范围

集合可用来定义要匹配的一个或多个字符。

[0123456789]可以简化为[0-9]

mysql> select prod_name
    -> from products
    -> where prod_name regexp '[1-5] Ton'
    -> order by prod_name;
+--------------+
| prod_name    |
+--------------+
| .5 ton anvil |
| 1 ton anvil  |
| 2 ton anvil  |
+--------------+
3 rows in set (0.00 sec)

匹配特殊字符

正则表达式语言由具有特定含义的特殊字符构成。我们已经看到.、[]、 |和-等,还有其他一些字符。

#下面的输出是错误的哦

mysql> select vend_name
    -> from vendors
    -> where vend_name regexp '.'
    -> order by vend_name;
+----------------+
| vend_name      |
+----------------+
| ACME           |
| Anvils R Us    |
| Furball Inc.   |
| Jet Set        |
| Jouets Et Ours |
| LT Supplies    |
+----------------+
6 rows in set (0.00 sec)


--下面是正确的
mysql> select vend_name
    -> from vendors
    -> where vend_name regexp '\\.'
    -> order by vend_name;
+--------------+
| vend_name    |
+--------------+
| Furball Inc. |
+--------------+
1 row in set (0.00 sec)

\.匹配.,所以只检索出一行。这种处理 就是所谓的转义(escaping),正则表达式内具有特殊意义的所 有字符都必须以这种方式转义。这包括.、|、[]以及迄今为止使用过的 其他特殊字符

在 MySQL 正则表达式中,空白元字符可以表示为以下表格:

元字符描述
\\n匹配换行符(newline)
\\r匹配回车符(carriage return)
\\t匹配制表符(tab)
\\f匹配换页符(form feed)
\\v匹配纵向制表符(vertical tab)

匹配字符类

字符类描述
[:alnum:]匹配任何一个字母或数字字符(相当于 [A-Za-z0-9]
[:alpha:]匹配任何一个字母字符(相当于 [A-Za-z]
[:digit:]匹配任何一个数字字符(相当于 [0-9]
[:lower:]匹配任何一个小写字母字符(相当于 [a-z]
[:upper:]匹配任何一个大写字母字符(相当于 [A-Z]
[:space:]匹配任何一个空白字符(包括空格、制表符、换行符等)

在正则表达式中,重复元字符用于指定匹配的重复次数。以下是一些常见的重复元字符及其描述:

元字符描述
*匹配前面的元素零次或多次。
+匹配前面的元素一次或多次。
?匹配前面的元素零次或一次。
{n}匹配前面的元素恰好 n 次。
{n,}匹配前面的元素至少 n 次。
{n,m}匹配前面的元素至少 n 次,但不超过 m 次。
mysql> select prod_name
    -> from products
    -> where prod_name regexp '\\([0-9] stick?\\)'
    -> order by prod_name;
+---------------+
| prod_name     |
+---------------+
| TNT (1 stick) |
+---------------+
1 row in set (0.00 sec)
mysql> select prod_name
    -> from products
    -> where prod_name regexp '[[:digit:]]{4}'
    -> order by prod_name;
+--------------+
| prod_name    |
+--------------+
| JetPack 1000 |
| JetPack 2000 |
+--------------+
2 rows in set (0.00 sec)

-- 正则表达式\\([0-9] sticks?\\)需要解说一下。\\(匹配),
-- [0-9]匹配任意数字(这个例子中为1和5),sticks?匹配stick
-- 和sticks(s后的?使s可选,因为?匹配它前面的任何字符的0次或1次出现),\\)匹配)。没有?,匹配stick和sticks会非常困难

正则表达式\\([0-9] sticks?\\)需要解说一下。\\(匹配)[0-9]匹配任意数字(这个例子中为15),sticks?匹配stick
和sticks(s后的?使s可选,因为?匹配它前面的任何字符的0次或1次出
现),\\)匹配)。没有?,匹配stick和sticks会非常困难

定位符

定位符描述
^匹配输入字符串的开头。
$匹配输入字符串的结尾。
\b匹配单词的边界。
\B匹配非单词边界。

^的双重用途 ^有两种用法。在集合中(用[和]定义),用它 来否定该集合,否则,用来指串的开始处

使REGEXP起类似LIKE的作用 本章前面说过,LIKE和REGEXP 的不同在于,LIKE匹配整个串而REGEXP匹配子串。利用定位 符,通过用^开始每个表达式,用$结束每个表达式,可以使 REGEXP的作用与LIKE一样

第七课 创建计算字段

字段(field) 基本上与列(column)的意思相同,经常互换使 用,不过数据库列一般称为列,而术语字段通常用在计算字段的 连接上。

存储在表中的数据都不是应用程序所需要的。 我们需要直接从数据库中检索出转换、计算或格式化过的数据;而不是 检索出数据,然后再在客户机应用程序或报告程序中重新格式化。

拼接字段

拼接(concatenate) 将值联结到一起构成单个值。

mysql> select concat (vend_name,'(',vend_country,')')
    -> from vendors
    -> order by vend_name;
+-----------------------------------------+
| concat (vend_name,'(',vend_country,')') |
+-----------------------------------------+
| ACME(USA)                               |
| Anvils R Us(USA)                        |
| Furball Inc.(USA)                       |
| Jet Set(England)                        |
| Jouets Et Ours(France)                  |
| LT Supplies(USA)                        |
+-----------------------------------------+
6 rows in set (0.01 sec)

Concat()拼接串,即把多个串连接起来形成一个较长的串。 Concat()需要一个或多个指定的串,各个串之间用逗号分隔。 上面的SELECT语句连接以下4个元素

  •  存储在vend_name列中的名字;
  •  包含一个空格和一个左圆括号的串;
  •  存储在vend_country列中的国家;
  •  包含一个右圆括号的串
mysql> select concat(rtrim(vend_name),'(',rtrim(vend_country),')')
    -> from vendors
    -> order by vend_name;
+------------------------------------------------------+
| concat(rtrim(vend_name),'(',rtrim(vend_country),')') |
+------------------------------------------------------+
| ACME(USA)                                            |
| Anvils R Us(USA)                                     |
| Furball Inc.(USA)                                    |
| Jet Set(England)                                     |
| Jouets Et Ours(France)                               |
| LT Supplies(USA)                                     |
+------------------------------------------------------+
6 rows in set (0.01 sec)

# RTrim()函数去掉值右边的所有空格。通过使用RTrim(),各个列都进行了整理。


# Trim函数 MySQL除了支持RTrim()(正如刚才所见,它去掉串右边的空格),还支持LTrim()(去掉串左边的空格)以及Trim()(去掉串左右两边的空格)。

使用别名

从前面的输出中可以看到,SELECT语句拼接地址字段工作得很好。 但此新计算列的名字是什么呢?实际上它没有名字,它只是一个值。如 果仅在SQL查询工具中查看一下结果,这样没有什么不好。但是,一个未 命名的列不能用于客户机应用中,因为客户机没有办法引用它

为了解决这个问题,SQL支持列别名。别名(alias)是一个字段或值 的替换名。别名用AS关键字赋予。请看下面的SELECT语句:

SELECT语句本身与以前使用的相同,只不过这里的语句中计算 字段之后跟了文本AS vend_title。它指示SQL创建一个包含 指定计算的名为vend_title的计算字段。从输出中可以看到,结果与以 前的相同,但现在列名为vend_title,任何客户机应用都可以按名引用 这个列,就像它是一个实际的表列一样。

mysql> select concat(Rtrim(vend_name),'(',rtrim(vend_country),')') as
    -> vend_title
    -> from vendors
    -> order by vend_name;
+------------------------+
| vend_title             |
+------------------------+
| ACME(USA)              |
| Anvils R Us(USA)       |
| Furball Inc.(USA)      |
| Jet Set(England)       |
| Jouets Et Ours(France) |
| LT Supplies(USA)       |
+------------------------+
6 rows in set (0.00 sec)

导出列 别名有时也称为导出列(derived column),不管称为 什么,它们所代表的都是相同的东西

别名的其他用途 别名还有其他用途。常见的用途包括在实际 的表列名包含不符合规定的字符(如空格)时重新命名它,在 原来的名字含混或容易误解时扩充它,等等

执行算数计算

mysql> SELECT prod_id, quantity, item_price
    ->     FROM OrderItems
    ->     WHERE order_num = 20005;
+---------+----------+------------+
| prod_id | quantity | item_price |
+---------+----------+------------+
| ANV01   |       10 |       5.99 |
| ANV02   |        3 |       9.99 |
| TNT2    |        5 |      10.00 |
| FB      |        1 |      10.00 |
+---------+----------+------------+
4 rows in set (0.00 sec)
  • 21
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不好,商鞅要跑

谢谢咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值