本章课程承接作者主页中《自学SQL》的第一章内容。
如果你恰好是程序小白、运营、产品,在工作中需要用到SQL,这套课程简直是为你量身定做。
本教程中的练习题,请移步 1024乐学编程-SQL基础 进行练习。
您也可以在该网站免费学习到更多课程。
本节将会和大家一起学习 SQL 的抽出条件中不可或缺的工具—— 谓词(predicate)。通俗来讲谓词就是上节中介绍的函数中的一种,是需要满足特定条件的函数,该条件就是 返回值是真值。对通常的函数来说,返回值有可能是数字、字符串或者日期等,但是谓词的返回值全都是真值(TRUE/FALSE/UNKNOWN)。这也是谓词和函数的最大区别。常用的谓词有:LIKE、BETWEEN、IS NULL、IS NOT NULL、IN、EXISTS。
上节课的内容我们已经涉及过一些谓词啦,这次我们展开来讲讲。
当需要进行字符串的部分一致查询时需要使用LIKE谓词。部分一致大体可以分为前方一致、中间一致和后方一致三种类型。接下来就让我们来看一看具体示例吧。
前方一致 select * from user where username like 'aaa%';
中间一致 select * from user where username like '%aaa%';
后方一致 select * from user where username like '%aaa';
“%”代表“0字符以上的任意字符串”的特殊符号。
注意:我们还可以使用“_”来代替“%”,不同的是,“_”代表“任意1个字符” 假定user表中的username 有一下三种情况:aaab、aaabb、aaaCbb。 如果想要查出“aaa”+任意1个字符的记录,可以使用下面的SQL :
select * from user where username like 'aaa_';
本节课的例子我们使用下面的表:
product_id | product_name | product_type | sale_price | purchase_price | regist_data |
---|---|---|---|---|---|
0001 | T恤衫 | 衣服 | 1000 | 500 | 2009-9-20 |
0002 | 打孔器 | 办公用品 | 500 | 320 | 2009-9-11 |
0003 | 运动T恤 | 衣服 | 4000 | 2800 | |
0004 | 菜刀 | 厨房用具 | 3000 | 2800 | 2009-9-20 |
0005 | 高压锅 | 厨房用具 | 6800 | 5000 | 2009-1-15 |
0006 | 叉子 | 厨房用具 | 500 | 2009-9-20 | |
0007 | 擦菜板 | 厨房用具 | 880 | 790 | 2008-4-28 |
0008 | 圆珠笔 | 办公用品 | 100 | 2009-11-11 |
为了选取出某些值为 NULL 的列的数据,不能使用 = ,而只能使用特定的谓词 IS NULL
选取出进货单价( purchase_price )为 NULL 的商品
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price IS NULL;
结果:
product_name | purchase_price |
---|---|
叉子 | |
圆珠笔 |
与此相反,想要选取 NULL 以外的数据时,需要使用 IS NOT NUL
选取进货单价( purchase_price )不为 NULL 的商品:
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price IS NOT NULL;
接下来让我们思考一下如何选取出进货单价( purchase _ price )为 320 元、 500 元、 5000 元的商品。这里使用之前学过的 OR 的SQL 语句
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price = 320
OR purchase_price = 500
OR purchase_price = 5000;
执行结果:
product_name | purchase_price |
---|---|
T恤衫 | 500 |
打孔器 | 320 |
高压锅 | 5000 |
虽然上述方法没有问题,但还是存在一点不足之处,那就是随着希望选取的对象越来越多,SQL 语句也会越来越长,阅读起来也会越来越困难。这时,我们就可以使用IN 谓词“ IN ( 值 , …… ) ”来替换上述 SQL 语句。
通过 IN 来指定多个进货单价进行查询:
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price IN (320, 500, 5000);
反之,希望选取出“进货单价不是 320 元、 500 元、 5000 元”的商品时,可以使用否定形式 NOT IN 来实现。
SELECT product_name, purchase_price
FROM Product
WHERE purchase_price NOT IN (320, 500, 5000);
product_name | purchase_price |
---|---|
运动T恤 | 2800 |
菜刀 | 2800 |
擦菜板 | 790 |
但需要注意的是,在使用 IN 和 NOT IN 时是无法选取出 NULL 数据的。实际结果也是如此,上述两组结果中都不包含进货单价为 NULL 的叉子和圆珠笔。 NULL 终究还是需要使用 IS NULL 和 IS NOT NULL 来进行判断。
本节最后将要给大家介绍的是 EXIST 谓词。将它放到最后进行学习
的原因有以下 3 点。
① EXIST 的使用方法与之前的都不相同
② 语法理解起来比较困难
③ 实际上即使不使用 EXIST ,基本上也都可以使用 IN (或者 NOT IN )来代替
理由①和②都说明 EXIST 是使用方法特殊而难以理解的谓词。特别是使用否定形式 NOT EXIST 的 SELECT 语句,即使是 DB 工程师也常常无法迅速理解。此外,如理由③所述,使用 IN 作为替代的情况非常多(尽管不能完全替代让人有些伤脑筋),很多读者虽然记住了使用方法但还是不能实际运用。
但是一旦能够熟练使用 EXIST 谓词,就能体会到它极大的便利性。
EXISTS 运算符用于判断查询子句是否有记录,如果有一条或多条记录存在返回 True,否则返回 False。
SELECT column_name(s)
FROM table_name
WHERE EXISTS
(SELECT column_name FROM table_name WHERE condition);
接下来我们做一道练习题,请移步到该网站的 《谓词》课程,习题在最后面 。
http://www.eluzhu.com:1818/my/course/64
到目前为止,我们看到的每条 SQL 语句中都只有一个查询条件。但在实际使用当中,往往都是同时指定多个查询条件对数据进行查询的。例如,想要查询“商品种类为厨房用具、销售单价大于等于 3000 ”或“进货单价大于等于 5000或小于 1000”的商品等情况。
在 WHERE 子句中使用 NOT运算符、AND 运算符 或者 OR 运算符,可以对多个查询条件进行组合。
通过 NOT 运算符可以生成“不是~”这样的查询条件。不能单独使用,必须和其他查询条件组合起来使用。
AND 运算符在其两侧的查询条件都成立时整个查询条件才成立,其意思相当于“并且”。
OR 运算符在其两侧的查询条件有一个成立时整个查询条件都成立,其意思相当于“或者” 。
例如,从 Product 表中选取出“商品种类为厨房用具( product_type = ' 厨房用具 ' ),并且销售单价大于等于 3000 ( sale_price >= 3000 )的商品”的查询条件中就使用了 AND 运算符。
在 WHERE 子句的查询条件中使用 AND 运算符:
SELECT product_name, sale_price
FROM Product
WHERE product_type = ' 厨房用具 '
AND sale_price >= 3000;
执行结果:
product_name | sale_price |
---|---|
菜刀 | 3000 |
高压锅 | 6800 |
该查询条件的文氏图如图。左侧的圆圈代表符合查询条件“商品种类为厨房用具”的商品,右侧的圆圈代表符合查询条件“销售单价大于等于 3000 ”的商品。两个圆重合的部分(同时满足两个查询条件的商品)就是通过 AND 运算符能够选取出的记录。
选取出“商品种类为厨房用具( product _ type = ' 厨房用具 ' ),或者销售单价大于等于 3000 ( sale_price >= 3000 )的商品”的查询条件中使用了 OR 运算符
SELECT *
FROM Product
WHERE product_type = '厨房用具'
OR sale_price >= 3000;
执行结果:
product_id | product_name | product_type | sale_price | purchase_price | regist_data |
---|---|---|---|---|---|
0003 | 运动T恤 | 衣服 | 4000 | 2800 | |
0004 | 菜刀 | 厨房用具 | 3000 | 2800 | 2009-9-20 |
0005 | 高压锅 | 厨房用具 | 6800 | 5000 | 2009-1-15 |
0006 | 叉子 | 厨房用具 | 500 | 2009-9-20 | |
0007 | 擦菜板 | 厨房用具 | 880 | 790 | 2008-4-28 |
接下来我们尝试书写稍微复杂一些的查询条件。例如,使用下面的查询条件对 Product 表进行查询的 SELECT 语句,其 WHERE 子句的条件表达式该怎么写呢?“商品种类为办公用品”并且“登记日期是 2009 年 9 月11日或者 2009 年 9 月 20 日”满足上述查询条件的商品( product _ name )只有“打孔器”。
按照上述的条件你来写出查询的表达式吧。
好的!我认为表达式应该这么写。SELECT * FROM product WHERE peoduct_type = '办公用品' AND regist_date = '2009-09-11' OR regist_date = '2009-09-20';
让我们马上执行上述 SELECT 语句试试看,会得到这样的错误结果。
product_id | product_name | product_type | sale_price | purchase_price | regist_data |
---|---|---|---|---|---|
0001 | T恤衫 | 衣服 | 1000 | 500 | 2009-9-20 |
0002 | 打孔器 | 办公用品 | 500 | 320 | 2009-9-11 |
0004 | 菜刀 | 厨房用具 | 3000 | 2800 | 2009-9-20 |
0006 | 叉子 | 厨房用具 | 500 | 2009-9-20 |
不想要的T恤、菜刀和叉子也被选出来了,真是头疼呀!到底为什么会出现这样的结果呢?
这是 AND 运算符优先于 OR 运算符所造成的。条件表达式会被解释成下面这样。
「 product_type = ' 办公用品 ' AND regist_date = '2009-09-11' 」
OR
「 regist_date = '2009-09-20' 」
也就是,
“商品种类为办公用品,并且登记日期是 2009 年 9 月11日”
或者
“登记日期是 2009 年 9 月 20 日”
这和想要指定的查询条件并不相符。
想要优先执行 OR 运算符时,可以像这样使用半角括号( )将 OR 运算符及其两侧的查询条件括起来。
SELECT product_name, product_type, regist_date
FROM Product
WHERE product_type = ' 办公用品 '
AND ( regist_date = '2009-09-11'
OR regist_date = '2009-09-20');
执行结果:
product_name | product_type | regist_date |
---|---|---|
打孔器 | 办公用品 | 2009-09-11 |
这样就选取出了想要得到的“打孔器”。
最后我们做一道练习题,请移步到该网站的 《逻辑运算符》课程中,习题在内容最后。
1024乐学编程-SQL基础
好,我们这次先讲到这里,请进入作者主页继续学习后续的SQL课程。或进入上面的地址免费学习完整的SQL课程。