SQL 必知必会- 第三课 排序检索数据

Posted Roki Zhang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL 必知必会- 第三课 排序检索数据相关的知识,希望对你有一定的参考价值。

目录

DISTINCT

        不能部分使用 DISTINCT

第 0 行

ORDER BY

        ORDER BY 子句的位置

        通过非选择列进行排序

        按多个列排序

        指定排序方向


DISTINCT

        顾名思义,它指示数据库只返回不同的值。

        不能部分使用 DISTINCT

        DISTINCT 关键字作用于所有的列,不仅仅是跟在其后的那一列。例如,你指定SELECT DISTINCT vend_id, prod_price,除非指定的两列完全相同,否则所有的行都会被检索出来。


第 0 行

        第一个被检索的行是第0 行,而不是第1 行。因此,LIMIT 1 OFFSET1 会检索第2 行,而不是第1 行。


ORDER BY

        为了明确地排序用SELECT 语句检索出的数据,可使用ORDER BY 子句。ORDER BY 子句取一个或多个列的名字,据此对输出进行排序。

SELECT prod_name FROM Products ORDER BY prod_name;

        ORDER BY 子句的位置

        在指定一条ORDER BY 子句时,应该保证它是SELECT 语句中最后一条子句。如果它不是最后的子句,将会出现错误消息。

        通过非选择列进行排序

        通常,ORDER BY 子句中使用的列将是为显示而选择的列。但是,实际上并不一定要这样,用非检索的列排序数据是完全合法的。

SELECT prod_name FROM Products ORDER BY prod_id;

        按多个列排序

        经常需要按不止一个列进行数据排序。例如,如果要显示雇员名单,可能希望按姓和名排序(首先按姓排序,然后在每个姓中再按名排序)。如果多个雇员有相同的姓,这样做很有用。
        要按多个列排序,简单指定列名,列名之间用逗号分开即可(就像选择多个列时那样)。
下面的代码检索3 个列,并按其中两个列对结果进行排序——首先按价格,然后按名称排序。

SELECT prod_id, prod_price, prod_name FROM Products ORDER BY prod_price, prod_name;

        重要的是理解在按多个列排序时,排序的顺序完全按规定进行。

        换句话说,对于上述例子中的输出,仅在多个行具有相同的prod_price 值时才对产品按prod_name 进行排序。如果prod_price 列中所有的值都是唯一的,则不会按prod_name 排序。

        指定排序方向

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

        请注意,DESC 是DESCENDING 的缩写,这两个关键字都可以使用。

        与DESC相对的是ASC(或ASCENDING),在升序排序时可以指定它。但实际上,ASC 没有多大用处,因为升序是默认的(如果既不指定ASC 也不指定DESC,则假定为ASC)。

读书笔记SQL必知必会

章节标题页数进度完成时间
1了解SQL1~9100%2022-04-08 
2检索数据 SELECT10~22100%2022-04-10
3排序检索数据 ORDER BY23~30100%2022-04-11
4过滤数据 WHERE31~38100%2022-04-11
5高级数据过滤 (组合WHERE,NOT,IN)39~49100%2022-04-16
6用通配符进行过滤 LIKE(%  _  [])49~57100%2022-04-18
7创建计算字段58~670%
8使用函数处理数据68~770%
9汇总数据78~880%
10分组数据89~980%
11使用子查询99~1070%
12联结表108~1190%
13创建高级联结120~1300%
14组合查询131~1390%
15插入数据140~1490%
16更新和删除数据150~1560%
17创建和操纵表157~1660%
18使用视图167~1770%
19使用存储过程178~1870%
20管理事务处理188~1950%
21使用游标196~202

0%

22高级SQL特性203~2150%

1. 了解SQL

重点知识:

1.1 本地安装MySQL(或派生的MariaDB),同时安装MySQL Workbench,如图所示:

1.2 win用户可以使用Microsoft SQL Server Express,这是个免费版本,它包括一个客户端:SQL Server Management Studio


2. 检索数据

检索数据章节开始,需要使用具体的表格,

因此需要先在本地实现附录A中的【供应商表】【产品表】【顾客表】【订单表】【订单物品表】5张表


附录A 样例表

表A-1 供应商表 Vendors

表A-1 Vendors表【供应商】
序号列名说明
1vend_id唯一的供应商ID (主键)
2vend_name供应商的名字
3vend_address供应商的地址
4vend_city供应商所在城市
5vend_province供应商所在的省
6vend_zip供应商地址邮政编码
7vend_country供应商所在国家

表A-2 产品表 Products

表A-2 Products表【产品】
序号列名说明
1prod_id唯一的产品id(主键)
2vend_id产品供应商id(外键,关联至供应商表A-1)
3prod_name产品名
4prod_price产品价格
5prod_desc产品描述

表A-3 顾客表 Customers

表A-3 Customers表【顾客】
序号列名说明
1cust_id唯一的顾客id(主键)
2cust_name顾客名
3cust_address顾客的地址
4cust_city顾客所在城市
5cust_province顾客所在省
6cust_zip顾客地址邮政编码
7cust_country顾客所在国家
8cust_contact顾客的联系名(类似昵称)
9cust_email顾客的email
10cust_sex顾客性别
11cust_telphone顾客手机号
12cust_age顾客年龄
13cust_marriage

顾客婚姻状态

14cust_weixin顾客微信

表A-4 订单表 Orders

表A-4 Orders表 【订单表】
序号列名预科
1order_num订单号(主键)
2order_date订单日期
3cust_id顾客id(外键,关联至顾客表A-3)

表A-5 订单物品表 OrderItems

表A-5 OrderItems表 【订单物品表】
序号列名说明
1order_num订单号(外键,关联至订单表A-4)(联合主键)
2order_item订单物品号(订单内的顺序,第几个)(联合主键)
3prod_id产品id(外键,关联至产品表A-2)
4quantity物品数量
5item_price物品价格

样例表的SQL下载地址:http://forta.com/books/0135182794

-----------------------------------------------------
-- Sams Teach Yourself SQL in 10 Minutes, 5th Edition
-- http://forta.com/books/0135182794/
-- Example table creation scripts for MySQL & MariaDB
-----------------------------------------------------

use your_db;

-- ----------------------
-- Create Customers table
-- ----------------------
CREATE TABLE Customers
(
  cust_id      char(10)  NOT NULL ,
  cust_name    char(50)  NOT NULL ,
  cust_address char(50)  NULL ,
  cust_city    char(50)  NULL ,
  cust_state   char(5)   NULL ,
  cust_zip     char(10)  NULL ,
  cust_country char(50)  NULL ,
  cust_contact char(50)  NULL ,
  cust_email   char(255) NULL 
);

-- -----------------------
-- Create OrderItems table
-- -----------------------
CREATE TABLE OrderItems
(
  order_num  int          NOT NULL ,
  order_item int          NOT NULL ,
  prod_id    char(10)     NOT NULL ,
  quantity   int          NOT NULL ,
  item_price decimal(8,2) NOT NULL 
);


-- -------------------
-- Create Orders table
-- -------------------
CREATE TABLE Orders
(
  order_num  int      NOT NULL ,
  order_date datetime NOT NULL ,
  cust_id    char(10) NOT NULL 
);

-- ---------------------
-- Create Products table
-- ---------------------
CREATE TABLE Products
(
  prod_id    char(10)      NOT NULL ,
  vend_id    char(10)      NOT NULL ,
  prod_name  char(255)     NOT NULL ,
  prod_price decimal(8,2)  NOT NULL ,
  prod_desc  text          NULL 
);

-- --------------------
-- Create Vendors table
-- --------------------
CREATE TABLE Vendors
(
  vend_id      char(10) NOT NULL ,
  vend_name    char(50) NOT NULL ,
  vend_address char(50) NULL ,
  vend_city    char(50) NULL ,
  vend_state   char(5)  NULL ,
  vend_zip     char(10) NULL ,
  vend_country char(50) NULL 
);


-- -------------------
-- Define primary keys
-- -------------------
ALTER TABLE Customers ADD PRIMARY KEY (cust_id);
ALTER TABLE OrderItems ADD PRIMARY KEY (order_num, order_item);
ALTER TABLE Orders ADD PRIMARY KEY (order_num);
ALTER TABLE Products ADD PRIMARY KEY (prod_id);
ALTER TABLE Vendors ADD PRIMARY KEY (vend_id);


-- -------------------
-- Define foreign keys
-- -------------------
ALTER TABLE OrderItems ADD CONSTRAINT FK_OrderItems_Orders FOREIGN KEY (order_num) REFERENCES Orders (order_num);
ALTER TABLE OrderItems ADD CONSTRAINT FK_OrderItems_Products FOREIGN KEY (prod_id) REFERENCES Products (prod_id);
ALTER TABLE Orders ADD CONSTRAINT FK_Orders_Customers FOREIGN KEY (cust_id) REFERENCES Customers (cust_id);
ALTER TABLE Products ADD CONSTRAINT FK_Products_Vendors FOREIGN KEY (vend_id) REFERENCES Vendors (vend_id);

-------------------------------------------------------
-- Sams Teach Yourself SQL in 10 Minutes, 5th Edition
-- http://forta.com/books/0135182794/
-- Example table population scripts for MySQL & MariaDB
-------------------------------------------------------


-- ------------------------
-- Populate Customers table
-- ------------------------
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES('1000000001', 'Village Toys', '200 Maple Lane', 'Detroit', 'MI', '44444', 'USA', 'John Smith', 'sales@villagetoys.com');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact)
VALUES('1000000002', 'Kids Place', '333 South Lake Drive', 'Columbus', 'OH', '43333', 'USA', 'Michelle Green');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES('1000000003', 'Fun4All', '1 Sunny Place', 'Muncie', 'IN', '42222', 'USA', 'Jim Jones', 'jjones@fun4all.com');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES('1000000004', 'Fun4All', '829 Riverside Drive', 'Phoenix', 'AZ', '88888', 'USA', 'Denise L. Stephens', 'dstephens@fun4all.com');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact)
VALUES('1000000005', 'The Toy Store', '4545 53rd Street', 'Chicago', 'IL', '54545', 'USA', 'Kim Howard');

-- ----------------------
-- Populate Vendors table
-- ----------------------
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('BRS01','Bears R Us','123 Main Street','Bear Town','MI','44444', 'USA');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('BRE02','Bear Emporium','500 Park Street','Anytown','OH','44333', 'USA');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('DLL01','Doll House Inc.','555 High Street','Dollsville','CA','99999', 'USA');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('FRB01','Furball Inc.','1000 5th Avenue','New York','NY','11111', 'USA');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('FNG01','Fun and Games','42 Galaxy Road','London', NULL,'N16 6PS', 'England');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES('JTS01','Jouets et ours','1 Rue Amusement','Paris', NULL,'45678', 'France');

-- -----------------------
-- Populate Products table
-- -----------------------
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BR01', 'BRS01', '8 inch teddy bear', 5.99, '8 inch teddy bear, comes with cap and jacket');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BR02', 'BRS01', '12 inch teddy bear', 8.99, '12 inch teddy bear, comes with cap and jacket');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BR03', 'BRS01', '18 inch teddy bear', 11.99, '18 inch teddy bear, comes with cap and jacket');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BNBG01', 'DLL01', 'Fish bean bag toy', 3.49, 'Fish bean bag toy, complete with bean bag worms with which to feed it');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BNBG02', 'DLL01', 'Bird bean bag toy', 3.49, 'Bird bean bag toy, eggs are not included');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BNBG03', 'DLL01', 'Rabbit bean bag toy', 3.49, 'Rabbit bean bag toy, comes with bean bag carrots');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('RGAN01', 'DLL01', 'Raggedy Ann', 4.99, '18 inch Raggedy Ann doll');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('RYL01', 'FNG01', 'King doll', 9.49, '12 inch king doll with royal garments and crown');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('RYL02', 'FNG01', 'Queen doll', 9.49, '12 inch queen doll with royal garments and crown');

-- ---------------------
-- Populate Orders table
-- ---------------------
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20005, '2020-05-01', '1000000001');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20006, '2020-01-12', '1000000003');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20007, '2020-01-30', '1000000004');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20008, '2020-02-03', '1000000005');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20009, '2020-02-08', '1000000001');

-- -------------------------
-- Populate OrderItems table
-- -------------------------
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20005, 1, 'BR01', 100, 5.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20005, 2, 'BR03', 100, 10.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20006, 1, 'BR01', 20, 5.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20006, 2, 'BR02', 10, 8.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20006, 3, 'BR03', 10, 11.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20007, 1, 'BR03', 50, 11.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20007, 2, 'BNBG01', 100, 2.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20007, 3, 'BNBG02', 100, 2.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20007, 4, 'BNBG03', 100, 2.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20007, 5, 'RGAN01', 50, 4.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20008, 1, 'RGAN01', 5, 4.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20008, 2, 'BR03', 5, 11.99);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20008, 3, 'BNBG01', 10, 3.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20008, 4, 'BNBG02', 10, 3.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20008, 5, 'BNBG03', 10, 3.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20009, 1, 'BNBG01', 250, 2.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20009, 2, 'BNBG02', 250, 2.49);
INSERT INTO OrderItems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20009, 3, 'BNBG03', 250, 2.49);


2.2 查询一个列

select prod_name from local.Products

注意:

如果没有明确排序查询结果,则返回的数据没有特定的顺序

SQL语句必须以分号结尾

SQL的关键字不区分大小写,SQL关键字推荐全部大写

SQL语句不受换行和多个空格影响


效果如下:


2.3 检索所有列

使用通配符* 可以返回表中所有列

注意:

列的顺序一般是表中出现的物理顺序,但并不总是如此

* 会降低检索速度

* 能检索出未知列


2.5 检索不同的值

例如: 查询Products表中的所有产品的供应商,要求无重复的供应商

SELECT vend_id FROM Products;

 由于产品表中 3个供应商 提供了9个商品,所以供应商出现了重复

只需要:  DISTINCT + 列名即可

SELECT DISTINCT vend_id FROM Products;

注意:

DISTINCT 必须直接放在 列名的 前面


DISTINCT 作用于 所有的查询的列,

如果是查vend_id,prod_price列,则是两两组合的结果唯一 


2.6 限制结果

如果只想返回第1行或者一定数的行,则有不同的写法

序号数据库语句说明
1SQL ServerSELECT TOP 5 prod_name FROM Products;TOP 5
2DB2

SELECT prod_name FROM Products

FETCH FIRST 5 ROWS ONLY;

FETCH FIRST 5 ROWS ONLY
3Oracle

SELECT prod_name FROM Products

WHERE ROWNUM <= 5;

WHERE ROWNUM <= 5
4MySQL, MariaDB, PostgreSQL或者SQLite

SELECT prod_name FROM Products

LIMIT 5;

或者 LIMIT 5 OFFSET 0

或者 简写

LIMIT 0,5(注意反过来了)


2.7 使用注释

序号注释示例说明
1# 这是一条注释在一行的开头使用#,某些DBMS不支持
2-- 这是一条注释行内注释,推荐,-- 后面就是注释
3/*   n行  */多行注释,常用于注释代码

3. 排序检索数据 ORDER BY

指定一条ORDER BY 子句时,应该要保证它是SELECT语句中的最后一条子句

ORDER BY子句使用的列名,可以不是显示的列,用非检索的列进行排序是完全合法。


3.2 按多个列排序

要按多个列排序,只需要列表之间用逗号分隔即可。

SELECT prod_id, prod_price, prod_name FROM products ORDER BY prod_price, prod_name;

mysql> SELECT prod_id, prod_price, prod_name FROM products ORDER BY prod_price, prod_name;
+---------+------------+---------------------+
| prod_id | prod_price | prod_name           |
+---------+------------+---------------------+
| BNBG02  |       3.49 | Bird bean bag toy   |
| BNBG01  |       3.49 | Fish bean bag toy   |
| BNBG03  |       3.49 | Rabbit bean bag toy |
| RGAN01  |       4.99 | Raggedy Ann         |
| BR01    |       5.99 | 8 inch teddy bear   |
| BR02    |       8.99 | 12 inch teddy bear  |
| RYL01   |       9.49 | King doll           |
| RYL02   |       9.49 | Queen doll          |
| BR03    |      11.99 | 18 inch teddy bear  |
+---------+------------+---------------------+
9 rows in set (0.00 sec)

3.3 按显示列的相对位置排序(从1开始数)

与上面完全等价:2表示第2列,即prod_price

SELECT prod_id, prod_price, prod_name FROM products ORDER BY 2, 3;

好处:不用再写一遍列名

缺点:难维护,长期变动可能错乱;

如果进行排序的列,没有在SELECT清单里,就无法使用相对位置了

mysql> SELECT prod_id, prod_price, prod_name FROM products ORDER BY 2, 3;
+---------+------------+---------------------+
| prod_id | prod_price | prod_name           |
+---------+------------+---------------------+
| BNBG02  |       3.49 | Bird bean bag toy   |
| BNBG01  |       3.49 | Fish bean bag toy   |
| BNBG03  |       3.49 | Rabbit bean bag toy |
| RGAN01  |       4.99 | Raggedy Ann         |
| BR01    |       5.99 | 8 inch teddy bear   |
| BR02    |       8.99 | 12 inch teddy bear  |
| RYL01   |       9.49 | King doll           |
| RYL02   |       9.49 | Queen doll          |
| BR03    |      11.99 | 18 inch teddy bear  |
+---------+------------+---------------------+
9 rows in set (0.00 sec)

3.4 指定排序方向

默认为升序:ASC可省略


降序使用DESC,

DESC关键字只应用到直接位于它前面的列名

如果要在多个列上降序,则必须对每一列指定DESC关键字


SELECT prod_id, prod_price, prod_name FROM products ORDER BY prod_price DESC, prod_name;

这句SQL没有为prod_name指定方向,因此默认为ASC升序。

mysql> SELECT prod_id, prod_price, prod_name FROM products ORDER BY prod_price DESC, prod_name;
+---------+------------+---------------------+
| prod_id | prod_price | prod_name           |
+---------+------------+---------------------+
| BR03    |      11.99 | 18 inch teddy bear  |
| RYL01   |       9.49 | King doll           |
| RYL02   |       9.49 | Queen doll          |
| BR02    |       8.99 | 12 inch teddy bear  |
| BR01    |       5.99 | 8 inch teddy bear   |
| RGAN01  |       4.99 | Raggedy Ann         |
| BNBG02  |       3.49 | Bird bean bag toy   |
| BNBG01  |       3.49 | Fish bean bag toy   |
| BNBG03  |       3.49 | Rabbit bean bag toy |
+---------+------------+---------------------+
9 rows in set (0.00 sec)

4. 过滤数据

搜索条件(search criteria)也称为过滤条件(filter condition)

WHERE子句,在表名之后给出。


同时使用WHERE子句 和 ORDER BY子句时,WHERE子句在前面

4.2 WHERE子句操作符

表4-1 WHERE子句操作符
序号操作符说明
1=等于
2<>不等于
3!=不等于
4<小于
5<=小于等于
6!<不小于
7>大于
8>=大于等于
9!>不大于
10BETWEEN X AND Y在指定值之间  [X, Y]
11IS NULL为NULL值

SELECT prod_name, prod_price FROM products WHERE prod_price BETWEEN 5 AND 10;

mysql> SELECT prod_name, prod_price FROM products
    -> WHERE prod_price BETWEEN 5 AND 10;
+--------------------+------------+
| prod_name          | prod_price |
+--------------------+------------+
| 8 inch teddy bear  |       5.99 |
| 12 inch teddy bear |       8.99 |
| King doll          |       9.49 |
| Queen doll         |       9.49 |
+--------------------+------------+
4 rows in set (0.00 sec)

4.3 检查空值 NULL

SELECT cust_name, cust_email FROM customers WHERE cust_email IS NULL;

客户表中,email为NULL的行

mysql> SELECT cust_name, cust_email FROM customers WHERE cust_email IS NULL;
+---------------+------------+
| cust_name     | cust_email |
+---------------+------------+
| Kids Place    | NULL       |
| The Toy Store | NULL       |
+---------------+------------+
2 rows in set (0.00 sec)

5. 组合WHERE(AND 、OR操作符)和 (NOT、IN)

SQL允许给出多个WHERE子句

这些WHERE子句有2种使用方式:AND子句 或者 OR子句

AND 和 OR 也被称为 逻辑操作符


5.1 AND操作符

5.2 OR 操作符

许多DBMS 在 OR子句的第1个条件满足时,就不再计算第2个条件了  ???

SELECT name FROM GIRLS WHERE age = 13 OR age = 14;


5.3 求值顺序

SQL在处理OR操作符之前,优先处理AND操作符。

AND 在求值过程中,优先级更高。

解决办法:任何时候,都使用 圆括号 ()对 AND 和 OR 操作符明确分组!

mysql> SELECT prod_name, prod_price
    -> FROM products
    -> WHERE (vend_id = 'DLL01' OR vend_id = 'BRS01') AND prod_price >= 10;
+--------------------+------------+
| prod_name          | prod_price |
+--------------------+------------+
| 18 inch teddy bear |      11.99 |
+--------------------+------------+
1 row in set (0.00 sec)

将前面两个条件 用 圆括号 括了起来,

因为圆括号具有比AND和OR更高的优先级。


5.2 IN操作符

指定条件范围,范围中的每条件都可进行匹配。

mysql> SELECT prod_name, prod_price
    -> FROM products
    -> WHERE vend_id IN ('DLL01', 'BRS01')
    -> ORDER BY prod_name;
+---------------------+------------+
| prod_name           | prod_price |
+---------------------+------------+
| 12 inch teddy bear  |       8.99 |
| 18 inch teddy bear  |      11.99 |
| 8 inch teddy bear   |       5.99 |
| Bird bean bag toy   |       3.49 |
| Fish bean bag toy   |       3.49 |
| Rabbit bean bag toy |       3.49 |
| Raggedy Ann         |       4.99 |
+---------------------+------------+
7 rows in set (0.00 sec)

IN操作符 完成了 与OR操作符 相同的功能

IN的优点:

1. 有许多合法操作符时,IN操作符更加直观

2. 在与其他AND 和 OR 组合使用IN时,求值顺序更容易管理

3. IN操作符一般比组OR操作符执行更快

4. IN的最大优点是:可以包含其他 SELECT 语句,能够更加动态地建立WHERE子句。


5.3 NOT 操作符

NOT操作符只有一个功能:否定其后所跟的任何条件

NOT 从来不单独使用,它总是与其他操作符一起使用

尤其是在复杂的子句中,NOT非常有用。

例如:与IN操作符联合使用时,NOT可以非常简单找出与条件列表不匹配的行。

MariaDB支持使用NOT否定IN、BETWEEN和EXISTS子句。

大多数DBMS允许NOT否定任何条件。

NOT 有时也可用<>操作符来完成

mysql> SELECT prod_name
    -> FROM products
    -> WHERE NOT vend_id = 'DLL01'
    -> ORDER BY prod_name;
+--------------------+
| prod_name          |
+--------------------+
| 12 inch teddy bear |
| 18 inch teddy bear |
| 8 inch teddy bear  |
| King doll          |
| Queen doll         |
+--------------------+
5 rows in set (0.00 sec)

mysql> SELECT prod_name
    -> FROM products
    -> WHERE vend_id <> 'DLL01'
    -> ORDER BY prod_name;
+--------------------+
| prod_name          |
+--------------------+
| 12 inch teddy bear |
| 18 inch teddy bear |
| 8 inch teddy bear  |
| King doll          |
| Queen doll         |
+--------------------+
5 rows in set (0.00 sec)

以上是关于SQL 必知必会- 第三课 排序检索数据的主要内容,如果未能解决你的问题,请参考以下文章

SQL必知必会

SQL必知必会(第五版)

SQL必知必会笔记

《SQL必知必会》读书笔记上(第1~15章)

SQL必知必会-03

MySQL必知必会