SQL 必知必会- 第三课 排序检索数据
Posted Roki Zhang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL 必知必会- 第三课 排序检索数据相关的知识,希望对你有一定的参考价值。
目录
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 | 了解SQL | 1~9 | 100% | 2022-04-08 |
2 | 检索数据 SELECT | 10~22 | 100% | 2022-04-10 |
3 | 排序检索数据 ORDER BY | 23~30 | 100% | 2022-04-11 |
4 | 过滤数据 WHERE | 31~38 | 100% | 2022-04-11 |
5 | 高级数据过滤 (组合WHERE,NOT,IN) | 39~49 | 100% | 2022-04-16 |
6 | 用通配符进行过滤 LIKE(% _ []) | 49~57 | 100% | 2022-04-18 |
7 | 创建计算字段 | 58~67 | 0% | |
8 | 使用函数处理数据 | 68~77 | 0% | |
9 | 汇总数据 | 78~88 | 0% | |
10 | 分组数据 | 89~98 | 0% | |
11 | 使用子查询 | 99~107 | 0% | |
12 | 联结表 | 108~119 | 0% | |
13 | 创建高级联结 | 120~130 | 0% | |
14 | 组合查询 | 131~139 | 0% | |
15 | 插入数据 | 140~149 | 0% | |
16 | 更新和删除数据 | 150~156 | 0% | |
17 | 创建和操纵表 | 157~166 | 0% | |
18 | 使用视图 | 167~177 | 0% | |
19 | 使用存储过程 | 178~187 | 0% | |
20 | 管理事务处理 | 188~195 | 0% | |
21 | 使用游标 | 196~202 | 0% | |
22 | 高级SQL特性 | 203~215 | 0% |
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
序号 | 列名 | 说明 |
1 | vend_id | 唯一的供应商ID (主键) |
2 | vend_name | 供应商的名字 |
3 | vend_address | 供应商的地址 |
4 | vend_city | 供应商所在城市 |
5 | vend_province | 供应商所在的省 |
6 | vend_zip | 供应商地址邮政编码 |
7 | vend_country | 供应商所在国家 |
表A-2 产品表 Products
序号 | 列名 | 说明 |
1 | prod_id | 唯一的产品id(主键) |
2 | vend_id | 产品供应商id(外键,关联至供应商表A-1) |
3 | prod_name | 产品名 |
4 | prod_price | 产品价格 |
5 | prod_desc | 产品描述 |
表A-3 顾客表 Customers
序号 | 列名 | 说明 |
1 | cust_id | 唯一的顾客id(主键) |
2 | cust_name | 顾客名 |
3 | cust_address | 顾客的地址 |
4 | cust_city | 顾客所在城市 |
5 | cust_province | 顾客所在省 |
6 | cust_zip | 顾客地址邮政编码 |
7 | cust_country | 顾客所在国家 |
8 | cust_contact | 顾客的联系名(类似昵称) |
9 | cust_email | 顾客的email |
10 | cust_sex | 顾客性别 |
11 | cust_telphone | 顾客手机号 |
12 | cust_age | 顾客年龄 |
13 | cust_marriage | 顾客婚姻状态 |
14 | cust_weixin | 顾客微信 |
表A-4 订单表 Orders
序号 | 列名 | 预科 |
1 | order_num | 订单号(主键) |
2 | order_date | 订单日期 |
3 | cust_id | 顾客id(外键,关联至顾客表A-3) |
表A-5 订单物品表 OrderItems
序号 | 列名 | 说明 |
1 | order_num | 订单号(外键,关联至订单表A-4)(联合主键) |
2 | order_item | 订单物品号(订单内的顺序,第几个)(联合主键) |
3 | prod_id | 产品id(外键,关联至产品表A-2) |
4 | quantity | 物品数量 |
5 | item_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行或者一定数的行,则有不同的写法
序号 | 数据库 | 语句 | 说明 |
1 | SQL Server | SELECT TOP 5 prod_name FROM Products; | TOP 5 |
2 | DB2 | SELECT prod_name FROM Products FETCH FIRST 5 ROWS ONLY; | FETCH FIRST 5 ROWS ONLY |
3 | Oracle | SELECT prod_name FROM Products WHERE ROWNUM <= 5; | WHERE ROWNUM <= 5 |
4 | MySQL, 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子句操作符
序号 | 操作符 | 说明 |
1 | = | 等于 |
2 | <> | 不等于 |
3 | != | 不等于 |
4 | < | 小于 |
5 | <= | 小于等于 |
6 | !< | 不小于 |
7 | > | 大于 |
8 | >= | 大于等于 |
9 | !> | 不大于 |
10 | BETWEEN X AND Y | 在指定值之间 [X, Y] |
11 | IS 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 必知必会- 第三课 排序检索数据的主要内容,如果未能解决你的问题,请参考以下文章