1 SELECT语句基础
SQL语句由简单的英语单词组成。这些单词称为关键字,每个SQL语句都是由一个或多个关键字组成。
SELECT 语句是 SQL 语句中使用最多的最基本的 SQL 语句。它的用途是从一个或多个表中选出(SELECT)必要数据的意思。
使用SELECT语句检索表数据,必须明确——想选择什么,以及从什么地方选择。
注:作为SQL组成部分的保留字。关键字不能用作表和列的名字。
1.1 列的查询
基本的SELECT语句
SELECT <列名>,……
FROM <表名>;
(处理SQL语句时,空格均可以被忽略。SQL语句可以在一行给出,也可以便于阅读,分为多行。)
该 SELECT 语句包含了 SELECT 和 FROM 两个子句(clause)。子句是 SQL 语句的组成要素,是以 SELECT 或者 FROM 等作为起始的短语。
SELECT 子句中列举了希望从表中查询出的列的名称,而 FROM 子句则指定了选取出数据的表的名称。
从Product表中输出3列
SELECT product_id, product_name, purchase_price
FROM Product;
查询出的列的顺序可以任意指定。查询多列时,需要使用逗号进行分隔,但最后一个列名后不加。查询结果中列的顺序和SELECT 子句中的顺序相同。
1.2 查询出表中所有的列
想要查询出全部列时,可以使用代表所有列的星号(*)。
查询全部的列
SELECT *
FROM <表名>;
输出Product表中全部的列
SELECT *
FROM Product;
得到的结果和下列的 SELECT 语句的结果相同。
SELECT product_id, product_name, product_type, sale_price,
purchase_price, regist_date
FROM Product;
星号(*)代表全部列的意思。
使用星号的话,无法设定列的显示顺序。这时就会按照 CREATE TABLE 语句的定义对列进行排序。使用通配符有个大优点,由于不明确指定列,所以能检索出名字未知的列。
随意使用换行符
SQL 语句使用换行符或者半角空格来分隔单词,在任何位置进行分隔都可以。原则上希望大家能够以子句为单位进行换行(子句过长时,为方便起见可以换行)。
SELECT
*
FROM
Product
;
另外,像下面这样插入空行(无任何字符的行)会造成执行错误。
SELECT *
FROM Product;
1.3 为列设定别名
SQL语句可以使用 AS 关键字为列设定别名。
为列设定别名
SELECT product_id AS id,
product_name AS name,
purchase_price AS price
FROM Product;
别名可以使用中文,使用中文时需要用双引号(")括起来 。不是单引号(')。
设定中文别名
SELECT product_id AS "商品编号",
product_name AS "商品名称",
purchase_price AS "进货单价"
FROM Product;
1.4 常数的查询
查询常数
SELECT '商品' AS string, 38 AS number, '2009-02-24' AS date,
product_id, product_name
FROM Product;
SELECT 子句中的第一列'商品'是字符串常数 ,第 2列38 是数字常数,第3 列'2009-02-24'是日期常数。
1.5 从结果中删除重复行
在SELECT语句中使用DISTINCT可以删除重复行。
SELECT DISTINCT product_type
FROM Product;
在使用 DISTINCT 时,NULL 也被视为一类数据。NULL 存在于多行中时,也会被合并为一条 NULL 数据。
对含有NULL数据的列使用DISTINCT关键字
SELECT DISTINCT purchase_price
FROM Product;
DISTINCT 也可以在多列之前使用。此时,会将多个列的数据进行组合,将重复的数据合并为一条。
在多列之前使用DISTINCT
SELECT DISTINCT product_type, regist_date
FROM Product;
product_type 列为 '厨房用具',同时regist_date 列为 '2009-09-20' 的两条数据被合并成了一条。
DISTINCT 关键字只能用在第一个列名之前。
1.6 根据WHERE语句来选择记录
SELECT 语句通过 WHERE 子句来指定查询数据的条件。
SELECT语句中的WHERE子句
SELECT <列名>, ……
FROM <表名>
WHERE <条件表达式>;
用来选取product_type列为'衣服'的记录的SELECT语句
SELECT product_name, product_type
FROM Product
WHERE product_type = '衣服';
WHERE 子句中的“product_type = '衣服'”就是用来表示查询条件的表达式(条件表达式)。等号是比较两边的内容是否相等的符号。Product 表的所有记录都会被进行比较。
如执行结果所示,首先通过WHERE 子句查询出符合指定条件的记录,然后再选取出 SELECT 语句指定的列。
也可以不选取出作为查询条件的列
SELECT product_name
FROM Product
WHERE product_type = '衣服';
SQL 中子句的书写顺序是固定的,不能随意更改。WHERE 子句必须 紧跟在FROM 子句之后,书写顺序发生改变的话会造成执行错误。
随意改变子句的书写顺序会造成错误
SELECT product_name, product_type
WHERE product_type = '衣服'
FROM Product;
1.7 注释的书写方法
注释是SQL 语句中用来标识 说明或者注意事项的部分。
注释对 SQL 的执行没有任何影响。因此,无论是英文字母还是汉字都可以随意使用。
注释的书写方法有如下两种。
1行注释
书写在“--”之后,只能写在同一行。
多行注释
书写在“/*”和“*/”之间,可以跨多行。
1行注释的使用示例
-- 本SELECT语句会从结果中删除重复行。
SELECT DISTINCT product_id, purchase_price
FROM Product;
多行注释的使用示例
/* 本SELECT语句,
会从结果中删除重复行。*/
SELECT DISTINCT product_id, purchase_price
FROM Product;
任何注释都可以插在 SQL 语句中。
在SQL语句中插入1行注释
SELECT DISTINCT product_id, purchase_price
-- 本SELECT语句会从结果中删除重复行。
FROM Product;
在SQL语句中插入多行注释
SELECT DISTINCT product_id, purchase_price
/* 本SELECT语句,
会从结果中删除重复行。*/
FROM Product;
2 算术运算符和比较运算符
2.1 算术运算符
SQL 语句中可以使用计算表达式。
SQL语句中使用运算表达式
SELECT product_name, sale_price,
sale_price * 2 AS "sale_price_x2"
FROM Product;
运算以行为单位执行的。
SQL 语句中可以使用的四则运算。
四则运算所使用的运算符(+、-、*、/)称为算术运算符。
运算符就是使用其两边的值进行四则运算或者字符串拼接、数值大小比较等运算,并返回结果的符号。
加法运算符(+)前后如果是数字或者数字类型的列名的话,就会返回加法运算后的结果。
SQL 中也可以像平常的运算表达式那样使用括号 ( )。括号中运算表达式的优先级会得到提升,优先进行运算。
2.2 需要注意NULL
在 SQL 语句中进行如下运算时,结果会是什么?
全部都是 NULL。实际上所有包含 NULL 的计算,结果肯定是 NULL。
5/0 这样除数为 0 的话会发生错误,只有 NULL 除以 0 时不会发生错误,并且结果还是 NULL。
注:FROM子句在SELECT语句中并不是必不可少的,只使用SELECT子句进行计算也是可以的。
SELECT (100 + 200) * 3 AS calculation;
2.3 比较运算符
选取出sale_price列为500的记录
SELECT product_name, product_type
FROM Product
WHERE sale_price = 500;
像符号 = 这样用来比较其两边的列或者值的符号称为比较运算符。在 WHERE 子句中通过使用比较运算符可以组合出各种各样的条件表达式。
<>,“不等于”是代表否定含义的比较运算符。
选取出sale_price列的值不是500的记录
SELECT product_name, product_type
FROM Product
WHERE sale_price <> 500;
SQL 中主要的比较运算符如下:
这些比较运算符可以对字符、数字和日期等几乎所有数据类型的列和值进行比较。
选取出销售单价大于等于1000日元的记录
SELECT product_name, product_type, sale_price
FROM Product
WHERE sale_price >= 1000;
选取出登记日期在2009年9月27日之前的记录
SELECT product_name, product_type, regist_date
FROM Product
WHERE regist_date < '2009-09-27';
小于某个日期就是在该日期之前的意思。想要实现在某个特定日期(包含该日期)之后的查询条件时,可以使用代表大于等于的 >= 运算符。
在使用大于等于(>=)或者小于等于(<=)作为查询条件时,一定要注意不等号(<、>)和等号(=)的位置不能颠倒。
还可以使用比较运算符对计算结果进行比较。
WHERE子句的条件表达式中也可以使用计算表达式
SELECT product_name, sale_price, purchase_price
FROM Product
WHERE sale_price - purchase_price >= 500;
2.4 对字符串使用不等号时的注意事项
创建Chars表并插入数据
PRIMARY KEY (chr));
-- DML:插入数据
START TRANSACTION;
INSERT INTO Chars VALUES ('1');
INSERT INTO Chars VALUES ('2');
INSERT INTO Chars VALUES ('3');
INSERT INTO Chars VALUES ('10');
INSERT INTO Chars VALUES ('11');
INSERT INTO Chars VALUES ('222');
COMMIT;
选取出大于'2'的数据的SELECT语句
SELECT chr
FROM Chars
WHERE chr > '2';
为什么 10 和 11 比 2 大,没有取出?这里混淆了数字和字符串的定义,也就是说 2 和'2' 并不一样。
chr 列被定为字符串类型,在对字符串类型的数据进行大小比较时,使用的是和数字比较不同的规则,是按照字典顺序进行比较,即按照条目在字典中出现的顺序来进行排序。
该规则最重要的一点就是,以相同字符开头的单词比不同字符开头的单词更相近。
Chars 表chr 列中的数据按照字典顺序进行排序的结果如下所示。
2.5 不能对NULL使用比较运算符
选取进货单价为2800日元的记录
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price = 2800;
选取出进货单价不是2800日元的记录
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price <> 2800;
执行结果中“叉子”和“圆珠笔”由于进货单价不明(NULL),无法判定是不是 2800日元,没有显示。
选取进货单价为NULL 的记录时候的条件表达式该怎么写?
错误的SELECT语句(一条记录也取不出来)
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price = NULL;
SQL 提供了专门用来判断是否为 NULL 的IS NULL 运算符。
选取NULL的记录
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price IS NULL;
选取不是 NULL 的记录时,需要使用 IS NOT NULL 运算符。
选取不为NULL的记录
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price IS NOT NULL;
3 逻辑运算符
3.1 NOT运算符
运算符 NOT在SQL中表示否定意义。
NOT 不能单独使用,必须和其他查询条件组合起来使用。
选取出销售单价大于等于1000日元的记录
SELECT product_name, product_type, sale_price
FROM Product
WHERE sale_price >= 1000;
向上述查询条件中添加NOT运算符
SELECT product_name, product_type, sale_price
FROM Product
WHERE NOT sale_price >= 1000;
上述WHERE子句的查询条件和下列的查询条件是等价的
SELECT product_name, product_type
FROM Product
WHERE sale_price < 1000;
3.2 AND运算符和OR运算符
在 WHERE 子句中使用 AND 运算符或者 OR 运算符,可以对多个查询条件进行组合。
AND 运算符在其两侧的查询条件都成立时整个查询条件才成立,其意思相当于“并且”。
OR 运算符在其两侧的查询条件有一个成立时整个查询条件都成立,其意思相当于“或者”。
在WHERE子句的查询条件中使用AND运算符
SELECT product_name, purchase_price
FROM Product
WHERE product_type = '厨房用具'
AND sale_price >= 3000;
AND运算符的工作效果图
在WHERE子句的查询条件中使用OR运算符
SELECT product_name, purchase_price
FROM Product
WHERE product_type = '厨房用具'
OR sale_price >= 3000;
OR运算符的工作效果图
3.3 通过括号强化处理
写入条件表达式
SELECT product_name, product_type, regist_date
FROM Product
WHERE product_type = '办公用品'
AND regist_date = '2009-09-11'
OR regist_date = '2009-09-20';
不想要 T 恤衫、菜刀和叉子怎么办。
上述查询结果主要是 AND 运算符优先于 OR 运算符所造成的。如果想要实现不要 T 恤衫、菜刀和叉子的效果,必须要优先实现OR运算符。
通过使用括号让OR运算符先于AND运算符执行
SELECT product_name, product_type, regist_date
FROM Product
WHERE product_type = '办公用品'
AND ( regist_date = '2009-09-11'
OR regist_date = '2009-09-20');
3.4 逻辑运算符和真值
前面提到的三个运算符 NOT、AND 和 OR 称为逻辑运算符。
这里所说的逻辑就是对真值进行操作的意思。真值就是值为真(TRUE)或假 (FALSE)其中之一的值 。
逻辑运算符对比较运算符等返回的真值进行操作。AND 运算符两侧的真值都为真时返回真,除此之外都返回假。OR 运算符两侧的真值只要有一个不为假就返回真,只有当其两侧的真值都为假时才返回假。NOT运算符只是单纯的将真转换为假,将假转换为真。
真值表(truth table)对这类操作及其结果进行的总结。
真值表
查询条件为P AND(Q OR R)的真值表
真为1、假为0的真值表
3.5 含有NULL时的真值
NULL在使用逻辑运算符时也需要特别对待 。
前面介绍过“不能对 NULL 使用比较运算符”。例如:当Product(商品)表,商品“叉子”和“圆珠笔”的进货单价(purchase_price)为NULL。那么,对这两条记录使用查询条件 purchase_price = 2800(进货单价为 2800日元)的结果结果不为真。
那么,上述结果会为假吗?也不为假。因为,如果结果为假,那么对其进 行否定的条件 NOT purchase_price = 2800(进货单价不是 2800 日元)的结果应该为真。可是这会与前面“不能对 NULL 使用比较运算符”矛盾。
既不是真也不是假,这时真值是除真假之外的第三种值——不确定(UNKNOWN)。SQL 之外的语言也基本上只使用真和假这两种真值。与通常的逻辑运算被称为二值逻辑相对,只有 SQL 中 的逻辑运算被称为三值逻辑。