01
—
INSERT练习
向员工表中插入一条记录,要求符合以下条件:
- 员工号为6
- 姓名为“kevin”
- 部门号为1
- 工资为10000.00
- 其它字段为空
参考答案如下:
insert into emp(empno,ename,deptno,sal) values(6,'Kevin',1,10000.00);
02
—
SELECT查询
SELECT中的字段
-- columns in SELECT statementselect * from emp;select EMPNO,ENAME,DEPTNO,HIREDATE,SAL,COMM from emp;-- 上面两个SQL语句的效果一样,但规范的做法是把每个select字段都写出来 -- 查询部分字段select ename,sal from emp;select ename,sal,sal*12 from emp;select ename,sal,sal*12 as annual_salary from emp;-- as也可以省略select ename,sal,sal*12 annual_salary from emp;-- 对查询的字段可以增加别名增加字段的可读性-- 为了更加容易阅读,我们甚至可以使用汉字,这对中国人更加友好select ename,sal,sal*12 annual salary from emp; -- 出错select ename,sal,sal*12 "annual salary" from emp;select ename,sal,sal*12 select from emp;select ename,sal,sal*12 "select" from emp;select sal,sal/100 sal% from emp;select sal,sal/100 "sal%" from emp;
对查询的字段可以增加别名增加字段的可读性
练习
编写一个SQL语句,输出下面的结果(注意设置字段的别名是中文):
答案:
mysql> select empno 员工号,salary 月薪, salary*14 14薪 from employees;+-----------+----------+-----------+| 员工号 | 月薪 | 14薪 |+-----------+----------+-----------+| 1 | 20000.00 | 280000.00 || 2 | 19100.00 | 267400.00 || 3 | 23900.00 | 334600.00 || 4 | 15000.00 | 210000.00 || 5 | 14200.00 | 198800.00 || 6 | 9700.00 | 135800.00 || 7 | 8900.00 | 124600.00 || 8 | 14900.00 | 208600.00 || 9 | 15000.00 | 210000.00 |+-----------+----------+-----------+9 rows in set (0.00 sec)
DISTINCT 去重复值
同一字段中可能会出现重复值,使用关键词distinct可以去掉重复值,用法如下:
select distinct 字段名 from 表名;
使用下面的SQL语句查询出员工表中的所有的部门:
-- the DISTINCT keyword select deptno from emp; select distinct deptno from emp;
但这些部门中有重复的,我们可能只想知道有哪些部门,可以加上distinct关键字去掉重复的记录。
WHERE条件过滤
where的用法
如果需要从表中选取指定的数据,可将where子句添加到select语句,语法如下:
select 字段名 from 表名 where 字段 运算符 值;
where子句中的运算符
-- the WHERE clause-- 查询2010年之后入职的员工select ename,sal,deptno,hiredate from emp where hiredate>='2010-01-01'; select ename,sal,deptno,hiredate from emp where sal<10000;select ename,sal,deptno,hiredate from emp where deptno=3;-- 查询3部门的员工信息 -- 查询不是3部门的员工信息select ename,sal,deptno,hiredate from emp where deptno!=3;-- 另一种不等于的写法select ename,sal,deptno,hiredate from emp where deptno<>3;
下面的运算符可在 WHERE 子句中使用:
运算符 | 说明 |
= | 等于 |
<> 或!= | 不等于 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
AND、OR 和NOT运算符
and和or可以用在where子句中把两个或多个条件结合起来。and 运算符要求两个条件都成立;or运算符要求二个条件中只要有一个成立即可。语法如下:
下面的SQL语句查询出第2部门里工资大于等于一万的员工:
-- The AND,OR and NOT Operatorsselect * from emp where deptno=2 and sal>=10000; * from emp where deptno=2 or sal>=10000;
下面的SQL语句查询出第2部门或者工资大于等于一万的员工:
select * from emp where deptno=2 or sal>=10000;
AND和OR还可以结合起来使用,例如我们再增加一个and的条件要求在2015年以后入职的员工
postgres=# select * from employees where deptno=2 or salary>10000 and hire_date>'2015-01-01'; empno | name | deptno | email | hire_date | salary | managerno | manager_name-------+--------------+--------+---------------------+------------+----------+-----------+-------------- 4 | 赵六 | 1 | zhaoliu@qq.com | 2019-12-01 | 15000.00 | | 5 | 李明 | 3 | liming@qq.com | 2021-09-11 | 14200.00 | | 7 | 钱杰 | 3 | qianjie@outlook.com | 2019-06-12 | 8900.00 | | 8 | 程娟 | 3 | chengjuan@gmail.com | 2013-07-22 | 14900.00 | |(4 rows)
很多同学对这个SQL的结果看不懂,例如第二个记录李明的入职时间并不符合2015年以后入职的要求。我们前面讲了运算符的优先级的问题,乘除的优先级高于加减,这里and的优先级高于or,所以这个SQL语句又可以写成
select * from emp where deptno=2 or sal>=10000 and hiredate>'2015-01-01'; select * from emp where deptno=2 or (sal>=10000 and hiredate>'2015-01-01');
这样可读性性就强多了。
NOT可以否定条件,例如
select * from emp where not deptno=2;-- 相当于 select * from emp where deptno!=2;
练习
用两种写法(一种用not,另外一种不用not)写出符合下面条件的SQL。
查询员工表中部门号不是3并且工资大于10000的员工。
参考答案如下:
select * from emp where deptno<>3 and sal>10000; select * from emp where not (deptno=3 or sal<=10000);
IN匹配多个值
in运算符是在where子句中指定多个搜索条件时可以匹配的值。in运算符实际是多个or条件的合并。语法如下:
select 字段名 from 表名 where 字段名 in(值1,值2,...);
判断1是否在集合内
如果我们查询员工号为3、4或6的员工,我们可以写成
-- the IN operatorselect ename,empno from emp where empno=3 or empno=4 or empno=5;
但是另外一种更加简洁和容易理解的写法是:
select ename,empno from emp where empno in (3,4,5);
这两种写法是等价的,但第二种写法在or的条件中的值多的时候更加有优势。
还可以用NOT判断不包括的值
select ename,empno from emp where empno not in (3,4,5);
BETWEEN指定范围
between运算符用于选取介于两个值之间的数据范围内的值,这些值可以是数字,字符串或日期。between 运算符包括开始和结束值,相当于>= and <=。
语法如下:
select 字段名 from 表名 where 字段名 between 值1 and 值2;
下面的SQL语句查询出在2013年之间入职的员工的姓名:
-- the BETWEEN operatorselect ename,hiredate from emp where hiredate>= '2013-01-01' and hiredate <='2013-12-31';
可以使用between把这个SQL改写成
select ename,hiredate from emp where hiredate between '2013-01-01' and '2013-12-31';
Not between是只不包括,如果把上面的between 改成not between,就是查询出不在2013年入职的员工:
select ename,hiredate from emp where hiredate not between '2013-01-01' and '2013-12-31';
相当于
select ename,hiredate from emp where hiredate<'2013-01-01' or hiredate>'2013-12-31';
LIKE搜索匹配的字符串
在 WHERE 子句中使用 LIKE 运算符来搜索匹配字符串中的指定模式,百分号(%)匹配零个、一个或多个字符,下划线(_)匹配单个字符。语法如下:
select 字段名 from 表名 where 字段 like 字符串;
下面的SQL语句找出名字中"J"开头的员工:
-- the LIKE operatorselect * from emp where ename like 'J%';
我们查询名字中有个“a”字的员工
select * from emp where ename like '%a%';
找出第三个字符是a的
select * from emp where ename like '__a%';
not like与like相反
ORDER BY排序
order by用于对结果集进行排序,默认按升序(asc)进行排序,也可以指定desc按降序对结果集进行排序。语法如下:
select 字段名 from 表名 order by 字段1,字段2,... asc|desc;
下面SQL语句按工资从低到高列出员工姓名和工资:
-- the ORDER BY clauseselect ename,deptno,sal from emp order by sal;
如果要按从高到低输出,加上desc的关键字:
select ename,deptno,sal from emp order by sal desc;
还可以用别名排序
还可以用多字段排序
select ename,deptno,sal from emp order by deptno,sal;
这里是先按部门号,再按工资进行排序。
对不同的字段可以分别采用升序和降序进行排列,其中升序asc默认可以省略。
select ename,deptno,sal from emp order by deptno desc,sal asc;
可以看到MySQL和SQL Server是把NULL作为最大值,而Oracle和PostgreSQL则相反。
SQL语言的注释
单行注释用- - 开头,MySQL还要加一个空格,其它三种数据库不用加空格。
多行注释与C语言相同的程序注释符号,即“/**/”。
-- 单行注释/* 这是一个多行的注视这里是新的一行结束行*/select name from employees where empno=1;
两个减号后面有空格。
如果我们有一个写好的SQL暂时不想执行,也可以用注释封起来
-- 单行注释/* 多行的注释这里是新的一行结束行*/select ename,sal,hiredate from emp where hiredate>'2020-01-01' order by sal; -- select ename,sal,hiredate from emp where hiredate>'2020-01-01' order by sal; /* select ename,sal,hiredate from emp where hiredate>'2020-01-01' order by sal; */ select ename,sal,hiredate from emp -- where hiredate>'2020-01-01' order by sal; select ename,sal,hiredate from emp /* where hiredate>'2020-01-01' order by sal */;
未完,请查看SQL语言基础(三)