SQL 数据查询 SELECT语句

数据查询 SELECT

SELECT 查找的列
FROMWHERE 查找条件
(一般前三行就够了)
GROUP BY 列名(分组查询)
	HAVING 条件
ORDER BY 列名 ASC/DESC 升序(默认)/降序

假设数据库中有四个表:

T(T_id, TNAME, TITLE)

C(C_id, CNAME, T_id)

S(S_id, SNAME, AGE, SEX)

SC(S_id, C_id, SCORE)

SELECT:

1.* 返回元组(记录)的所有列

列出S表中所有男生的信息
SELECT *
FROM S
WHERE SEX='M';

2.ALL/DISTINCT 全部显示(默认)/消除重复项目

列出学生姓名,去除重复项
SELECT DISTINCT SNAME 消除重复的学生名
FROM S;

3.COUNT(*) 计算元组(记录)的条数、COUNT(列名) 计算列中的有值的行的个数、SUM(列名)、AVG(列名)、MAX(列名)、MIN(列名)

列出S表中男生的人数,年龄平均值
SELECT COUNT(*),AVG(AGE)
FROM S
WHERE SEX='M';

4.LOWER(列名)/UPPER(列名),将列的内容小写/大写

5.ROUND 四舍五入、TRUNC 取整、MOD 取余等函数

WHERE:

1.>、=等比较运算符,<>和!=表示不等于

列出年龄大于18的学生姓名
SELECT SNAME
FROM S
WHERE AGE>18;

2.AND、OR、NOT逻辑运算符

列出年龄大于18的男生姓名
SELECT SNAME
FROM S
WHERE AGE>18 AND SEX='M';

3.IN、NOT IN

列出年龄是1819的学生姓名
SELECT SNAME
FROM S
WHERE AGE IN (18,19);

4.BETWEEN … AND/NOT BETWEEN AND

(同上)列出年龄是1819的学生姓名
SELECT SNAME
FROM S
WHERE AGE BETWEEN 18 AND 19;

5.IS NULL 查看某一项是否为空

6.LIKE 匹配类似字符串

_ 代表单字,% 代表零个或多个字

a%b_: a开头,倒数第二个字是b的字符串

找到名字最后一个字是k的学生。
SELECT SNAME
FROM S
WHERE SNAME LIKE '%k';

7.|| 连接两个列,不留空格

将学生学号和姓名一起列出
SELECT S_id|| SNAME
FROM S;

8.连接相关:=

内连接:两个表一 一对应,表1中的某项不会找不到对应

找出Morty所选课程的编号
SELECT C_id
FROM S,SC
WHERE S.S_id=SC.S_id AND SNAME='Morty'; 将两个表建立连接,通过共有的列
如果是3个表,就需要2个连接,4个表就要3个连接。

外连接:两个表不是一 一对应,可能表1中的某些元组没有对应

列出S和SC中的S_id
假设SC中还有几个学生的编号没写入
SELECT S.S_id,SC.S_id
FROM S,SC
WHERE S.S_id=SC.S_id(+);
那么结果会是,S中所有的S_id都输出了,而SC中有几条S_id是空值NULL

用JOIN、USING等也可以(这里没细讲,书上95页有)

SELECT e.employee_id, e.last_name, d.location_id
FROM   employees e JOIN departments d
USING (department_id);

上下这两个,都是e、d两个表根据department_id连接

SELECT e.employee_id, e.last_name, e.department_id, 
       d.department_id, d.location_id
FROM   employees e JOIN departments d
ON     (e.department_id = d.department_id);

9.嵌套相关:IN、NOT IN、EXISTS、NOT EXISTS、UNIQUE

不相关子查询

内查询 不需要 用 外查询的表

只执行一遍内查询

找到选择课程C2的学生和学号
SELECT S_id,SNAME
FROM S
WHERE S_id IN(SELECT S_id
           FROM SC
           WHERE C_id='C2');
先执行内查询,找到SC中C2课程的所有学生的学号,得到一个学号的表
再执行外查询,找到学号在刚刚学号表里的学生

相关子查询

内查询 需要 用 外查询的表

IN

找到选择课程C2的学生和学号
SELECT S_id,SNAME
FROM S
WHERE 'C2' IN(SELECT C_id
           FROM SC
           WHERE SC.S_id=S.S_id);
类似for语句,先执行外查询,对S中的每一行,都执行一遍内查询
比如,当外查询查到学生S1时,内查询就变成:
SELECT C_id
FROM SC
WHERE SC.S_id=S1;
内查询就得到S1所选的所有课程的编号,如果C2在这些编号里,S1就被选中。
接下来查S2,再次进行内查询:
SELECT C_id
FROM SC
WHERE SC.S_id=S2;
......
外查询有多少个元组,有多少个学生,内查询就要执行多少次

EXISTS(SELECT …) 如果内查询 SELECT 的结果为非空,EXISTS 返回真;结果为空,EXISTS 返回假

SELECT S_id,SNAME
FROM S
WHERE EXISTS(SELECT *
           FROM SC
           WHERE SC.S_id=S.S_id AND C_id='C2');
和上面类似,这里也像for一样,先执行外查询,对每一个学生,都执行一遍内查询,查到S1时,内查询变为:
SELECT *
FROM SC
WHERE SC.S_id=S1 AND C_id='C2';查到S1学生选课程C2的记录,如果S1没选C2时,结果就为空。外查询再根据查询结果是否为空,来决定是否选S1。
下面再把S2代入内查询......
外查询有多少个元组,内查询就要执行多少次
GROUP BY:

(有WHERE的话)GROUP BY (列名) 将 WHERE 找到的多行记录分组,分组依据是列名

然后 SELECT 按组输出,每组输出一行

SELECT   department_id, AVG(salary)
FROM     employees
GROUP BY department_id; 将员工按部门分组,输出每部门的平均工资

SELECT   department_id, job_id, SUM(salary)
FROM     employees
GROUP BY department_id, job_id ; 先将员工按部门分组,再按工作种类分组,输出同一部门中同一工作的工资总和
HAVING:

只可以在 GROUP BY 之后使用,对 GROUP BY 得到的各个分组进行筛选。

SELECT   department_id, MAX(salary)
FROM     employees
GROUP BY department_id 按部门号分组
HAVING   MAX(salary)>10000; 将部门内最高工资>10000的部门留下,其他的去掉
ORDER BY:

ORDER BY 列名(排序依据) ASC/DESC 升序(默认)/降序

ORDER BY AGE DESC
其他的:
起别名

在 SELECT 和 FROM 中,都可以在 表和列 后加 AS(可以省略),再加新名字

SELECT COUNT(*) "Number of Managers" 如果不是空格断开的字符串,就不需要双引号
...
集合的并、交、差:

UNION 、INTERSECT、EXCEPT

将两个查询结果做并、交、差。

SELECT ...
FROM ...
WHERE ...
UNION
SELECT ...
FROM ...
WHERE ...

建议还是多做练习理解,如书上83、84、85页

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值