SQL面试题
**1.
DDL :数据定义语言 create table .../ drop table ... / rename ... to..../ truncate table.../alter table ...
DML : 数据操纵语言**
insert into ... values ... update ... set ... where ... delete from ... where ...
2.
select 查询结果 如: [学号,平均成绩:组函数avg(成绩)] _from_ 从哪张表中查找数据 如:[涉及到成绩:成绩表score] _where_ 查询条件 如:[b.课程号='0003' and b.成绩>80] _group by_ 分组 如:每个学生的平均:按学号分组,MySQL中可以不用 _having_ 对分组结果指定条件 如:[大于60分] _order by_ 对查询结果排序 如:[增序: 成绩 ASC / 降序: 成绩 DESC];**
limit 使用limt子句返回topN(对应这个问题返回的成绩前两名)如:[ limit 2 _==>从0索引开始读取2个_] limit==>从0索引开始 [0,N-1]
① select * from table limit 2,1;
//含义是跳过2条取出1条数据,limit后面是从第2条开始读,读取1条信息,即读取第3条数据
② select * from table limit 2 offset 1;
//含义是从第1条(不包括)数据开始取出2条数据,limit后面跟的是2条数据,offset后面是从第1条开始读取,即读取第2,3条
组函数_: 去重 _distinct() 统计总数_sum()_ 计算个数_count()_ 平均数_avg()_ 最大值_max()_ 最小数_min()_
多表连接: 内连接_(__省略默认__inner__) join_ ..._on_..左连接_left join_ tableName _as_ b _on_ a.key ==b.key右连接_right join_ 连接_union(无重复(过滤去重)_)和_union all(有重复[不过滤去重]_)
3.日期
4.--问题:查询工资大于149号员工工资的员工的信息
select * from employees where salary>(select salary from employees where employees_id =149)
5.Insert
1用法
在标准的SQL语句中,一次插入一条记录的INSERT语句只有一种形式。
INSERT INTO tablename(列名…) VALUES(列值);
而在MySQL中还有另外一种形式。
INSERT INTO tablename SET column_name1 = value1, column_name2 = value2,…;
第一种方法将列名和列值分开了,在使用时,列名必须和列值的数一致。如下面的语句向users表中插入了一条记录:
INSERT INTO users(id, name, age) VALUES(123, '姚明', 25);
第二种方法允许列名和列值成对出现和使用,如下面的语句将产生同样的效果。
INSERT INTO users SET id = 123, name = '姚明', age = 25;
2不同点
(1): 如果使用了SET方式,必须至少为一列赋值。如果某一个字段使用了省缺值(如默认或自增值),这两种方法都可以省略这些字段。如id字段上使用了自增值,上面两条语句可以写成如下形式:
INSERT INTO users (name, age) VALUES('姚明',25);
INSERT INTO uses SET name = '姚明', age = 25;
(2)MySQL在VALUES上也做了些变化。 如果VALUES中什么都不写,那MySQL将使用表中每一列的默认值来插入新记录。
INSERT INTO users () VALUES();
如果表名后什么都不写,就表示向表中所有的字段赋值。使用这种方式,不仅在VALUES中的值要和列数一致,而且顺序不能颠倒。 INSERT INTO users VALUES(123, '姚明', 25);
如果将INSERT语句写成如下形式MySQL将会报错。如:
INSERT INTO users VALUES('姚明',25)
(3)标准的INSERT语句允许一次插入多条数据,set不行
INSERT INTO users (name, age) VALUES('姚明',25),('麦蒂',25)
6.首字母大写
SELECT
dname,
SUBSTR(dname,1,1),UPPER(SUBSTR(dname,1,1)),
SUBSTR(dname,2,LENGTH(dname)),
CONCAT(UPPER(SUBSTR(dname,1,1)),SUBSTR(dname,2,LENGTH(dname)))
FROM dept;
7.mysql日期
mysql时间日期类型
表示时间值的日期和时间类型为 DATETIME、DATE、TIMESTAMP、TIME和YEAR。
每个时间类型有一个有效值范围和一个"零"值,当指定不合法的MySQL不能表示的值时使用"零"值。
TIMESTAMP类型有专有的自动更新特性。
类型
大小(字节)
范围
格式
用途
DATE
3
1000-01-01/9999-12-31
YYYY-MM-DD
日期值
TIME
3
'-838:59:59'/'838:59:59'
HH:MM:SS
时间值或持续时间
YEAR
1
1901/2155
YYYY
年份值
DATETIME
8
1000-01-01 00:00:00/9999-12-31 23:59:59
YYYY-MM-DD HH:MM:SS
混合日期和时间值
TIMESTAMP
4
1970-01-01 00:00:00/2038结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07
YYYYMMDD HHMMSS
混合日期和时间值,时间戳
now()函数 存储的形式DATETIME
select YEAR(bithday) AS 年,MONTH(brihtday) 月,DAY(brithday) 日 from student;
7.1 date_format
日期转字符串,注意格式的大小写,不错错误
SELECT DATE_FORMAT(NOW(),'%Y-%m-%d')
SELECT DATE_FORMAT(NOW(),'%Y-%m-%d %H:%i:%s')
7.2 str_to_date
字符串转日期
SELECT STR_TO_DATE('2020-05-08','%Y-%m-%d') FROM emp
ps1:
两个时间串可以进行比较,但不可以直接进行加减,需要调用时间加减的函数完成。
ps2:
1.我们公司也是把业务日期设置为了 varchar类型,不建议这么设置。
如果是日期,建议使用date类型,如果还需要有时间部分,建议使用它datetime
因为如果用varchar 来存储年月日,那么需要10个字节,而date类型只需4个字节,而datetime类型也只需要8个字节,都小于varchar类型。
其次,在进行查找、比较时,由于date和datetime本质上存储在数据库中是一个数字,所以直接通过数值比较效率很高,而varchar进行比较 必需要一个字符一个字符比较,所以速度很慢。
2.将时间设置成string是偷懒的做法。虽然在string类型还是可以进行比较,如小于大于等于,问题如下:
- string类型的字节数大小远大于datetime等类型,造成空间浪费,datetime本质上是双int型;
- String类型的日期格式固定,无法像datetime一样调整显示格式,不同格式要进行join,需要两次类型转换;
- String类型无法处理时区等信息;
8.年薪统计
公司福利不错13薪,年底双薪,统计员工的年薪=sal_13+comm_13
副总不按月奖金计算
SELECT empno,ename,job,sal_13+comm_13 FROM emp;
SELECT empno,ename,job,sal_13+nvl(comm_13,0) FROM emp;
SELECT empno,ename,job,sal_13+nvl(comm_13,0) AS 年收入 FROM emp;
SELECT empno,ename,job,sal_13+nvl(comm_13,0) AS '年收入' FROM emp;
SELECT empno,ename,job,sal_13+nvl(comm_13,0) AS "年收入" FROM emp;
计算时字段为数值类型应该按0来计算,按null达不到我们预期效果。
ps:nvl()sql中的替代函数