SQL零基础投喂(基础查询与排序)

**

Task02:基础查询与排序

**

2.1.1 从表中选取数据
SELECT语句
从表中选取数据时需要使⽤SELECT语句,也就是只从表中选出(SELECT)必要数据的意
思。通过SELECT语句查询并选取出必要数据的过程称为匹配查询或查询(query)。
基本SELECT语句包含了SELECT和FROM两个⼦句(clause)。示例如下:
SELECT <列名> FROM <表名>;
其中,SELECT⼦句中列举了希望从表中查询出的列的名称,⽽FROM⼦句则指定了选取出数
据的表的名称。

2.1.2 从表中选取符合条件的数据
WHERE语句
当不需要取出全部数据,⽽是选取出满⾜“商品种类为⾐服”“销售单价在1000⽇元以上”等某
些条件的数据时,使⽤WHERE语句。
SELECT 语句通过WHERE⼦句来指定查询数据的条件。在WHERE ⼦句中可以指定“某⼀列的
值和这个字符串相等”或者“某⼀列的值⼤于这个数字”等条件。执⾏含有这些条件的SELECT
语句,就可以查询出只符合该条件的记录了。
SELECT <列名>,……
FROM <表名>
WHERE <条件表达式>;
⽐较下⾯两者输出结果的不同:
– 用来选取product type列为衣服’的记录的SELECT语句

SELECT product_name,product_type
FROM product
WHERE product_type = '衣服';

product_name | product_type
--------------±-------------
T恤衫 | 衣服
运动T恤 | 衣服
(2 行记录)
– 也可以选取出不是查询条件的列(条件列与输出列不同)
SELECT product_name
FROM product
WHERE product_type = ‘衣服’;

product_name

T恤衫
运动T恤
(2 行记录)

2.1.3 相关法则
 星号()代表全部列的意思。
 SQL中可以随意使⽤换⾏符,不影响语句执⾏(但不可插⼊空⾏)。
 设定汉语别名时需要使⽤双引号(")括起来。
 在SELECT语句中使⽤DISTINCT可以删除重复⾏。
 注释是SQL语句中⽤来标识说明或者注意事项的部分。分为1⾏注释"-- “和多⾏注释两
种”/
/"。
1 – 想要查询出全部列时,可以使用代表所有列的星号(
)。
2 SELECT *
3 FROM <表名>;
4 – SQL语句可以使用AS关键字为列设定别名(用中文时需要双引号(“”))。
5 SELECT product_id As id,
6 product_name As name,
7 purchase_price AS “进货单价”
8 FROM product;

id | name | 进货单价
------±--------±---------
0001 | T恤衫 | 500
0002 | 打孔器 | 320
0003 | 运动T恤 | 2800
0004 | 菜刀 | 2800
0005 | 高压锅 | 5000
0006 | 叉子 |
0007 | 擦菜板 | 790
0008 | 圆珠笔 |
(8 行记录)
9 – 使用DISTINCT删除product_type列中重复的数据
10 SELECT DISTINCT product_type
11 FROM product;

product_type

衣服
办公用品
厨房用具
(3 行记录)

2.2 算术运算符和⽐较运算符
2.2.1 算术运算符
SQL语句中可以使⽤的四则运算的主要运算符如下:
含义 运算符
加法 +
减法 -
乘法 *
除法 /

2.2.2 ⽐较运算符
1 – 选取出sale_price列为500的记录
2 SELECT product_name,product_type
3 FROM product
4 WHERE sale_price = 500;

product_name | product_type
--------------±-------------
打孔器 | 办公用品
叉子 | 厨房用具
(2 行记录)
SQL常⻅⽐较运算符如下:
运算符 含义
= 和~相等
<> 和~不相等

= ⼤于等于~
⼤于~
<= ⼩于等于~
< ⼩于~

2.2.3 常⽤法则
 SELECT⼦句中可以使⽤常数或者表达式。
 使⽤⽐较运算符时⼀定要注意不等号和等号的位置。
 字符串类型的数据原则上按照字典顺序进⾏排序,不能与数字的⼤⼩顺序混淆。
 希望选取NULL记录时,需要在条件表达式中使⽤IS NULL运算符。希望选取不是NULL的
记录时,需要在条件表达式中使⽤IS NOT NULL运算符。
相关代码如下:
1 – SQL语句中也可以使用运算表达式
2 SELECT product_name,sale_price,sale_price * 2 AS “sale_price x2”
3 FROM product;

product_name | sale_price | sale_price*2
--------------±-----------±-------------
T恤衫 | 1000 | 2000
打孔器 | 500 | 1000
运动T恤 | 4000 | 8000
菜刀 | 3000 | 6000
高压锅 | 6800 | 13600
叉子 | 500 | 1000
擦菜板 | 880 | 1760
圆珠笔 | 100 | 200
(8 行记录)
4 – WHERE子句的条件表达式中也可以使用计算表达式
5 SELECT product_name,sale_price,purchase_price
6 FROM product
7 WHERE sale_price-purchase_price >= 500;

product_name | sale_price | purchase_price
--------------±-----------±---------------
T恤衫 | 1000 | 500
运动T恤 | 4000 | 2800
高压锅 | 6800 | 5000
(3 行记录)
8 /* 对字符串使用不等号
9 首先创建chars并插入数据
10 选取出大于‘2’的SELECT语句*/
11 – DDL:创建表
12 CREATE TABLE chars(
13 chr CHAR(3) NOT NULL,
14 PRIMARY KEY (chr));
15 – 选取出大于’2’的数据的SELECT语句('2’为字符串)
16 SELECT chr
17 FROM chars
18 WHERE chr > ‘2’;
19 – 选取NULL的记录
20 SELECT product_name,purchase_price
21 FROM product
22 WHERE purchase_price IS NULL;

product_name | purchase_price
--------------±---------------
叉子 |
圆珠笔 |
(2 行记录)
23 – 选取不为NULL的记录
24 SELECT product_name,purchase_price
25 FROM product
26 WHERE purchase_price IS NOT NULL;

product_name | purchase_price
--------------±---------------
T恤衫 | 500
打孔器 | 320
运动T恤 | 2800
菜刀 | 2800
高压锅 | 5000
擦菜板 | 790
(6 行记录)

2.3 逻辑运算符
2.3.1 NOT运算符
想要表示“不是……”时,除了前⽂的<>运算符外,还存在另外⼀个表示否定、使⽤范围更⼴
的运算符:NOT。
NOT不能单独使⽤,如下例:
1 – 选取出销售单价大于等于1000日元的记录
2 SELECT product_name,product_type,sale_price
3 FROM product
4 WHERE sale_price >= 1000;

product_name | product_type | sale_price
--------------±-------------±-----------
T恤衫 | 衣服 | 1000
运动T恤 | 衣服 | 4000
菜刀 | 厨房用具 | 3000
高压锅 | 厨房用具 | 6800
(4 行记录)
5 – 向代码清单2-30的查询条件中添加NOT运算符
6 SELECT product_name,product_type,sale_price
7 FROM product
8 WHERE not sale_price >= 1000;

SELECT product_name,product_type,sale_price
FROM product
WHERE not sale_price >= 1000;

product_name | product_type | sale_price
--------------±-------------±-----------
打孔器 | 办公用品 | 500
叉子 | 厨房用具 | 500
擦菜板 | 厨房用具 | 880
圆珠笔 | 办公用品 | 100
(4 行记录)

2.3.2 AND运算符和OR运算符
当希望同时使⽤多个查询条件时,可以使⽤AND或者OR运算符。
AND 相当于“并且”,类似数学中的取交集;
OR 相当于“或者”,类似数学中的取并集。
通过括号优先处理
如果要查找这样⼀个商品,该怎么处理?
“商品种类为办公⽤品”并且“登记⽇期是 2009 年 9 ⽉ 11 ⽇或者 2009 年 9 ⽉ 20 ⽇”
理想结果为“打孔器”,但当你输⼊以下信息时,会得到错误结果
1 – 将查询条件原封不动地写入条件表达式,会得到错误结果
2 SELECT product_name, product_type, regist_date
3 FROM product
4 WHERE product_type = ‘办公用品’
5 AND regist_date = ‘2009-09-11’
6 OR regist_date = ‘2009-09-20’;
错误的原因是是 AND 运算符优先于 OR 运算符,想要优先执⾏OR运算,可以使⽤括号:
1 – 通过使用括号让OR运算符先于AND运算符执行
2 SELECT product_name, product_type, regist_date
3 FROM product
4 WHERE product_type = ‘办公用品’
5 AND ( regist_date = ‘2009-09-11’
6 OR regist_date = ‘2009-09-20’);

2.3.3 真值表
复杂运算时该怎样理解?
当碰到条件较复杂的语句时,理解语句含义并不容易,这时可以采⽤真值表来梳理逻辑关系。
什么是真值?
本节介绍的三个运算符 NOT、AND 和 OR 称为逻辑运算符。这⾥所说的逻辑就是对真值进⾏
操作的意思。真值就是值为真(TRUE)或假 (FALSE)其中之⼀的值。
例如,对于 sale_price >= 3000 这个查询条件来说,由于 product_name 列为 ‘运动 T 恤’
的记录的 sale_price 列的值是 2800,因此会返回假(FALSE),⽽ product_name 列为 ‘⾼
压锅’ 的记录的sale_price 列的值是 5000,所以返回真(TRUE)。
AND 运算符两侧的真值都为真时返回真,除此之外都返回假。
OR 运算符两侧的真值只要有⼀个不为假就返回真,只有当其两侧的真值都为假时才返回假。
NOT运算符只是单纯的将真转换为假,将假转换为真。
含有NULL时的真值
NULL的真值结果既不为真,也不为假,因为并不知道这样⼀个值。
那该如何表示呢?
这时真值是除真假之外的第三种值——不确定(UNKNOWN)。⼀般的逻辑运算并不存在这第
三种值。SQL 之外的语⾔也基本上只使⽤真和假这两种真值。与通常的逻辑运算被称为⼆值
逻辑相对,只有 SQL 中的逻辑运算被称为三值逻辑。
三值逻辑下的AND和OR真值表为:

练习题-第⼀部分
2.1
编写⼀条SQL语句,从product(商品)表中选取出“登记⽇期(regist在2009年4⽉28⽇之
后”的商品,查询结果要包含product name和regist_date两列。
select product_name,regist_date
from product p
where
(extract(year from p.regist_date) >= 2009
and extract(month from p.regist_date) >= 4)
or
(extract(year from p.regist_date) >= 2009
and extract(month from p.regist_date) >= 4
and extract(day from p.regist_date) >=28);
–或者时间戳 ::timestamp
select product_name,regist_date
from product p
where p.regist_date >= ‘2009-04-28’ ::timestamp;
product_name | regist_date
--------------±------------
T恤衫 | 2009-09-20
打孔器 | 2009-09-11
菜刀 | 2009-09-20
叉子 | 2009-09-20
圆珠笔 | 2009-11-11
(5 行记录)

2.2
请说出对product 表执⾏如下3条SELECT语句时的返回结果。

1 SELECT *
2 FROM product
3 WHERE purchase_price = NULL;
–从product表中选出purchase_price 等于 NULL的字段
1 SELECT *
2 FROM product
3 WHERE purchase_price <> NULL;
–从product表中选出purchase_price 不等于 NULL的字段
1 SELECT *
2 FROM product
3 WHERE product_name > NULL;
–从product表中选出purchase_price 大于 NULL的字段

2.3
代码清单2-22(2-2节)中的SELECT语句能够从product表中取出“销售单价(saleprice)
⽐进货单价(purchase price)⾼出500⽇元以上”的商品。请写出两条可以得到相同结果的SELECT语句。

select product_name,sale_price,purchase_price
from product
where sale_price-purchase_price >=500;

select product_name,sale_price,purchase_price,(sale_price-purchase_price) chajia
from product
having chajia>=500;

select product_name,sale_price,purchase_price
from(
select product_name,sale_price,purchase_price,sale_price-purchase_price chajia
from product) a
where a.chajia>=500;

product_name | sale_price | purchase_price
--------------±-----------±---------------
T恤衫 | 1000 | 500
运动T恤 | 4000 | 2800
高压锅 | 6800 | 5000
(3 行记录)

2.4
请写出⼀条SELECT语句,从product表中选取出满⾜“销售单价打九折之后利润⾼于100⽇元
的办公⽤品和厨房⽤具”条件的记录。查询结果要包括product_name列、product_type列以
及销售单价打九折之后的利润(别名设定为profit)。
提示:销售单价打九折,可以通过saleprice列的值乘以0.9获得,利润可以通过该值减去purchase_price列的值获得。

select * from(
select product_name,product_type,sale_price*0.9-purchase_price profit
from product
WHERE product_type = ‘办公用品’
or product_type = ‘厨房用具’) a
where a.profit>=100;

product_name | product_type | profit
--------------±-------------±-------
打孔器 | 办公用品 | 130.0
高压锅 | 厨房用具 | 1120.0
(2 行记录)

2.4 对表进⾏聚合查询
2.4.1 聚合函数
SQL中⽤于汇总的函数叫做聚合函数。以下五个是最常⽤的聚合函数:
COUNT:计算表中的记录数(⾏数)
SUM: 计算表中数值列中数据的合计值
AVG: 计算表中数值列中数据的平均值
MAX: 求出表中任意列中数据的最⼤值
MIN: 求出表中任意列中数据的最⼩值
1 – 计算全部数据的行数(包含NULL)
2 SELECT COUNT(*)
3 FROM product;
4 – 计算NULL以外数据的行数
5 SELECT COUNT(purchase_price)
6 FROM product;
7 – 计算销售单价和进货单价的合计值
8 SELECT SUM(sale_price), SUM(purchase_price)
9 FROM product;
10 – 计算销售单价和进货单价的平均值
11 SELECT AVG(sale_price), AVG(purchase_price)
12 FROM product;
13 – MAX和MIN也可用于非数值型数据
14 SELECT MAX(regist_date), MIN(regist_date)
15 FROM product;
使⽤聚合函数删除重复值
1 – 计算去除重复数据后的数据行数
2 SELECT COUNT(DISTINCT product_type)
3 FROM product;
4 – 是否使用DISTINCT时的动作差异(SUM函数)
5 SELECT SUM(sale_price), SUM(DISTINCT sale_price)
6 FROM product;
sum | sum
-------±------
16780 | 16280
(1 行记录)

2.4.2 常⽤法则
COUNT函数的结果根据参数的不同⽽不同。COUNT()会得到包含NULL的数据⾏数,⽽
COUNT(<列名>)会得到NULL之外的数据⾏数。
聚合函数会将NULL排除在外。但COUNT(
)例外,并不会排除NULL。
MAX/MIN函数⼏乎适⽤于所有数据类型的列。SUM/AVG函数只适⽤于数值类型的列。
想要计算值的种类时,可以在COUNT函数的参数中使⽤DISTINCT。
在聚合函数的参数中使⽤DISTINCT,可以删除重复数据。

2.5 对表进⾏分组
2.5.1 GROUP BY语句
之前使⽤聚合函数都是会整个表的数据进⾏处理,当你想将进⾏分组汇总时(即:将现有的数
据按照某列来汇总统计),GROUP BY可以帮助你:
1 SELECT <列名1>,<列名2>, <列名3>, ……
2 FROM <表名>
3 GROUP BY <列名1>, <列名2>, <列名3>, ……;

聚合键中包含NULL时
将进货单价(purchase_price)作为聚合键举例:
1 SELECT purchase_price, COUNT(*)
2 FROM product
3 GROUP BY purchase_price;

purchase_price | count
----------------±------
| 2
320 | 1
500 | 1
2800 | 2
5000 | 1
790 | 1
(6 行记录)
此时会将NULL作为⼀组特殊数据进⾏处理

GROUP BY书写位置
GROUP BY的⼦句书写顺序有严格要求,不按要求会导致SQL⽆法正常执⾏,⽬前出现过的
⼦句顺序为:
1 SELECT → 2. FROM → 3. WHERE → 4. GROUP BY
其中前三项⽤于筛选数据,GROUP BY对筛选出的数据进⾏处理

2.5.2 常⻅错误
在使⽤聚合函数及GROUP BY⼦句时,经常出现的错误有:

  1. 在聚合函数的SELECT⼦句中写了聚合健以外的列 使⽤COUNT等聚合函数时,SELECT
    ⼦句中如果出现列名,只能是GROUP BY⼦句中指定的列名(也就是聚合键)。
  2. 在GROUP BY⼦句中使⽤列的别名 SELECT⼦句中可以通过AS来指定别名,但在GROUP
    BY中不能使⽤别名。因为在DBMS中 ,SELECT⼦句在GROUP BY⼦句后执⾏。
  3. 在WHERE中使⽤聚合函数 原因是聚合函数的使⽤前提是结果集已经确定,⽽WHERE还处
    于确定结果集的过程中,所以相互⽭盾会引发错误。 如果想指定条件,可以在SELECT,
    HAVING(下⾯⻢上会讲)以及ORDER BY⼦句中使⽤聚合函数。

2.6 为聚合结果指定条件
2.6.1 ⽤HAVING得到特定分组
将表使⽤GROUP BY分组后,怎样才能只取出其中两组?
这⾥WHERE不可⾏,因为,WHERE⼦句只能指定记录(⾏)的条件,⽽不能⽤来指定组的条
件(例如,“数据⾏数为 2 ⾏”或者“平均值为 500”等)。
可以在GROUP BY后使⽤HAVING⼦句。
HAVING的⽤法类似WHERE

2.6.2 HAVING特点
HAVING⼦句⽤于对分组进⾏过滤,可以使⽤数字、聚合函数和GROUP BY中指定的列名(聚
合键)。
1 – 数字
2 SELECT product_type, COUNT()
3 FROM product
4 GROUP BY product_type
5 HAVING COUNT(
) = 2;
6 – 错误形式(因为product_name不包含在GROUP BY聚合键中)
7 SELECT product_type, COUNT(*)
8 FROM product
9 GROUP BY product_type
10 HAVING product_name = ‘圆珠笔’;

2.7 对查询结果进⾏排序
2.7.1 ORDER BY
SQL中的执⾏结果是随机排列的,当需要按照特定顺序排序时,可已使⽤ORDER BY⼦句。
1 SELECT <列名1>, <列名2>, <列名3>, ……
2 FROM <表名>
3 ORDER BY <排序基准列1>, <排序基准列2>, ……
默认为升序排列,降序排列为DESC
1 – 降序排列
2 SELECT product_id, product_name, sale_price, purchase_price
3 FROM product
4 ORDER BY sale_price DESC;
5 – 多个排序键
6 SELECT product_id, product_name, sale_price, purchase_price
7 FROM product
8 ORDER BY sale_price, product_id;
9 – 当用于排序的列名中含有NULL时,NULL会在开头或末尾进行汇总。
10 SELECT product_id, product_name, sale_price, purchase_price
11 FROM product
12 ORDER BY purchase_price;

SELECT product_id,product_name,sale_price,purchase_price
FROM product
ORDER BY purchase_price;
product_id | product_name | sale_price | purchase_price
------------±-------------±-----------±---------------
0002 | 打孔器 | 500 | 320
0001 | T恤衫 | 1000 | 500
0007 | 擦菜板 | 880 | 790
0003 | 运动T恤 | 4000 | 2800
0004 | 菜刀 | 3000 | 2800
0005 | 高压锅 | 6800 | 5000
0006 | 叉子 | 500 |
0008 | 圆珠笔 | 100 |
(8 行记录)

2.7.2 ORDER BY中列名可使⽤别名
前⽂讲GROUP BY中提到,GROUP BY ⼦句中不能使⽤SELECT ⼦句中定义的别名,但是在
ORDER BY ⼦句中却可以使⽤别名。为什么在GROUP BY中不可以⽽在ORDER BY中可以
呢?
这是因为SQL在使⽤ HAVING ⼦句时 SELECT 语句的顺序为:
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY。
其中SELECT的执⾏顺序在 GROUP BY ⼦句之后,ORDER BY ⼦句之前。也就是说,当在
ORDER BY中使⽤别名时,已经知道了SELECT设置的别名存在,但是在GROUP BY中使⽤别
名时还不知道别名的存在,所以不能在ORDER BY中可以使⽤别名,但是在GROUP BY中不
能使⽤别名

练习题-第⼆部分
2.5
请指出下述SELECT语句中所有的语法错误。

1 SELECT product_id,SUM(product name)
2 --本SELECT语句中存在错误。
3 FROM product
4 GROUP BY product_type
5 WHERE regist_date > ‘2009-09-01’;
–字段类型无法使用sum函数,没有匹配指定名称和参数类型的函数. 您也许需要增加明确的类型转换.

2.6
请编写⼀条SELECT语句,求出销售单价(sale_price列)合计值大于进货单价(purchase prilce列)合计值1.5倍的商品种类。

select * from (
select product_type,sum(sale_price) a,sum(purchase_price) b
from product
group by product_type) c
where c.a>1.5*c.b;

product_type | a | b
--------------±-----±-----
衣服 | 5000 | 3300
办公用品 | 600 | 320
(2 行记录)

2.7
此前我们曾经使⽤SELECT语句选取出了product(商品)表中的全部记录。当时我们使⽤了ORDERBY⼦句来指定排列顺序,但现在已经⽆法记起当时如何指定的了。请根据下列执⾏结果,思考ORDERBY⼦句的容。
–order by product_id

SELECT product_type,SUM(product_name)
FROM product
GROUP BY product_type;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值