mySQL语句以及常见面试题

 1.查看所有数据库
    show databases;
2.创建数据库
    create database newdb;
3.修改数据库字符集
    alete database newdb charset=gnb/utf-8;
4.使用数据库
    use newdb;
5.删除数据库
    drop database newdb;
6.创建数据库时指定 字符集
    create database newdb character set=gbk/utf/8;
7.创建表单
    create table info(id int,name varchar(10));
8.创建表单时指定引擎和字符集
    create table info(id int,name varchar(10))engin=myisam/innodb charset=gbk/utf-8;
9.查看表详情
    show create table info;
10.查看表结构
    desc info;
11.修改表名
    rename table info to emp;
12.修改表引擎和字符集
    alter table info engin=myisam/innodb charset=gbk/utf-8;
13.修改表字段
    alter table info change name ename varchar(10);
14.修改字段类型和位置
    alter table info modify name varchar(10) first/after id;
15.添加表字段
    alter table info add gender varchar(10) first/after name;
16.删除表
    drop tabale info;
17.全表插入
    inset into info values(1,'tom'),(2,'jim');
18.指定字段插入
    insert into info (id,name)values(3,'alen');
19.查询数据
    select * from emp;
20.查看所有表
    show tables;
21.删除表字段
    alter table info drop name;
22.删除表内某条数据
    delete from info where name='tom';
23.删除表单内所有数据
    delete form info;
24.删除表并并创建新表
    truncate table info;
25.修改数据
    update info set name = 'tom' where id=1;
26.解决windows乱码
    set names gbk;
27.主键约束+自增
    create table info(id int primary key auto_increment,name varchar(10)); 
28.注释
    create table info(id int primary key auto_increment comment '这是主键',name varchar(10));
29.事务相关
    - 开启事务: begin
    - 回滚事务: rollback
    - 提交事务: commit
    - 标记事务: savepoint s1
    - 回滚到标记事务: rollback to s1;
30.查看数据库提交状态
    show variables like '%autocommit%';
31.查看表提交状态
    show variables like '%character%';
32.修改数据提交 状态
    set autocommit=0/1;
33.SQL分类
    - DLL: 数据标记语言   create alter truncate (不支持事务)
    - DML: 数据操作语言   update insert delete select
    - DQL: 数据查询语言   select
    - TCL: 事务控制语言   begin rollback commit savepoint rollback to
    - DCL: 数据控制语言   用于分配用户使用权限
34.is null 判断是否为空值;  is not null 判断是否有值;
35.数据类型
    - 整数:int, bigint(m) m 代表显示长度,结合zreofill使用
    - 浮点数:double(m,d) m 代表显示长度,d 代表小数长度.高精度运算时使用 decimal
    - 字符串: char 长度为255,char长度超过255时使用text,text为可变字符串长度为 65535,varchar 可变长度字符串,长度为65535.
    - 日期类型: date time timestamp;
36.导入SQL数据
    - windows系统 scoure D:/tables.sql;
    - linux 系统 /home/用户名/桌面/tables.sql
37.别名
    select name as '别名' from emp;
    select name '别名' from emp;
    select name 别名 from emp;
38.去重
    select distinct date from info;
39.比较运算符
    - > < = != <> * / %
40.模糊查询
    _ 代表单个未知字符
    % 代表多个未知字符
    select * from emp where name like '%S%';
41.and 与 or 的区别
    and 与 java中的 && 一样
    or 与 Java中的 || 一样
42.查询某个字段的多个值
    select name from info where salary in(1000,2000,3000);
- 查询字段的值再两个值之间
    select name from info where salary betweem 1000 and 2000;
43.排序
    - 升序 order by 字段名 asc
    select * from emp order by deptno;
    - 降序 order by 字段名 desc
    select * from emp order by deptno desc;
    - 多段排序
    select * from emp order by deptno,salary desc;
44.分页查新
    - 公式:   limit ((跳过的页数-1)*每页数据的条数),每页显示的数据数量;
    select * from emp limit 1,10;
45.数值计算
    - + - * / %    7%2=mod(7,2)
    select name,comm*5 from emp;
46.日期相关函数
    1.获取当前日期时间
        select now();
    2.获取当前日期
        select data();
    3.获取当前时间
        select time();
    4.从年月日时分秒钟提取:年月日,时分秒
        select date(now());
        select time(now());
    5.从年月日时分秒中提取时间分量
        select extract(year from now());
        select extract(month from now());
        select extract(day from now());
        select extract(hour from now());
        select extract(mintue from now());  
        selecet extract(second from now());
47.日期格式化
    - 格式:   %Y 四位年; %y 两位年; %m 两位月; %c 一位月; %d 日; %H  24小时; %h 12小时; %i 分; %s 秒;
    1. 把默认时间格式转换为:年月日时分秒
        select date_format(now(),'%Y年%m月%d日%H时%i分%s秒'); 
    2.把非标准时间转换为默认格式
        select str_to_date('10.12.2018','%d.%m.%Y %H:%i:%s');
48.ifnull(x,y);
    例:age = ifnull(x,y)如果x的值为null,那么age的值为y;如果x的值不为null,那么age的值为x.
49.聚合函数
    - 平均值: avg(salary);
    - 统计值: count(*/salary);
    - 求和值: sum(salary);
    - 最大值: max(salary);
    - 最小值: min(salary);
50.字符串相关
    - 字符串拼接 concat(字段名,'字符串')
        select ename,concat(salary,'$') from emp;
    - 获取字符串长度 char_length()
        select enamr,char_length(ename) from emp;
    - 获取字符串在另一个字符串出现的位置
        1. instr('字符串','要查询的')
            select instr('ethan','t');
        2. locate(substr,str)
            select locate('t','Ethan');
    - 插入字符串insert(str,start,length,newstr)
            select insert('ethan',1,4,'m');
    - 转大写 upper()
            select upper('abc');
    - 转小写 lower()
            select lower('ABC');
    - 去除两端空白 trim
            select trim('       abc ');
    - 截取字符串
        1.左侧开始截取 left()
            select left('tom',2);
        2.右侧开始截取
            select right('tom',2);
        3.全局截取 substring(str,start)/substring(str,start,length);
            select substring('tom',1);
            select substring('tom',1,2);
    - 重复 repeat()
            select repeat('tom',2);
    - 替换 replace()
            select replace('tmo','t','T');
    - 反转 reverse()
            select reverse('cba');
51.数学相关的函数
    1.向下取整
        select floor(3.1456);
    2.四舍五入
        select round(3.45);
    3.round(num,m);
        select round(22.879,2);
    4.非四舍五入
        select truncate(22.873,2);
    5.随机数rand()
        select floor(rand()*3+3);
52.分组查询
    - group by 字段名
        select deptno,avg(salary) from emp group by deptno;
    - 多字段分组查询
        select deptno,mgr,count(*) from emp where mgr is not null group by deptno,mgr;
53.having
    1.having后面可以写普通字段的条件,也可以写聚合函数的条件,但是不推荐在having后面写普通条件
    2.where后面不可以写聚合函数
    3.having 要结合group by 分组查询使用
54.子查询/嵌套查询
    select * from emp where salary > (select avg(salary) from emp);
55.关联查询:一次查询多张表
    select e.name,d.name from emp e,dept d where e.deptno = d.deptno;
56.等值连接和内连接
    1.等值连接: select * from a,b where a.x = b.x and a.age=18;
    2.内连接: select a.* from a join b on a.id = b.id where a.age=18;
    3.外连接
        - 左外连接: select a.*,b.* from a left join b on a.id = b.id and where age = 18;
        - 右外连接: select a.*,b.* from a right join b on a.id = b.id where a.age = 18;
        - 查询 a,b两张表的数据,如果查询量两张表的交集数据使用内连接或等值连接,如果查询某一张表的全部数据和另一张表的交集数据则用外连接
57.表设计之关联关系
    - 什么是外键:主键是用于表示数据唯一性的字段,外键是用来建立关系的字段,值通常指向另一张主键的表
    - 一对一关系:有A,B两张表,A表中一条数据对应B表中的一条数据,称为一对一关系.应用场景用户表和用户信息扩展表,商品表信息扩展表
    - 一对多:AB两张表,A表中的一条数据对应B表数据中的多条数据,同时B表中的一条对应A表中的一条数据.应用场景:员工表和部门表,商品表和商品分类表
    - 多对多:AB两张表,A表中的一条数据对应B表中的多条数据,同时B表中的一条数据对应A表中的多条数据.应用场景:老师表和学生表.
58.自关联
    - 当前表的外键指向当前表的主键,这种关联方式叫自关联
    - 应用场景:需要保存上下级关系时
59.连接方式和关联方式
    - 连接方式:包括等值连接,内连接,外连接,是指查询多张表数据使用的查询方式
    - 关联关系:包括一对一,一对多,多对多,是指设计表时,两张表之间存在的逻辑关系
60.视图
    - 什么是视图:数据库中的表和视图都是其内部的对象,视图可以理解成为一张虚拟的表,视图的本质就是取代了一条SQL语句.
    - 为什么使用视图:因为数据查询需要书写大量的SQL语句,每次书写效率太低,使用视图可以起到重用SQL的作用,视图可以隐藏敏感信息.
    - 创建视图
        - create view 视图名 as 子查询
            - 创建一个10号部门员工的视图
                create view v_emp_10 as(select * from emp where deptno = 10);
    - 从视图中查询数据
        select * from v_emp_10;
    - 创建一个没有工资的视图
        create view v_emp_noSalary as(select empno,ename,job from emp);
61.视图的分类
    - 简单的分类: 创建视图的子查询不能包含:去重,函数分组,关联查询,可以对视图中的数据进行增删改查
    - 复杂视图:和简单视图相反,只能对视图中的数据进行查询操作
        - 创建一个复杂视图
             create view info as(select avg(salary),count(*),max(salary)from emp);
62.对简单的视图进行增删改查,操作方式和table一样
    - 插入数据
        insert into v_emp_10(empno,ename,deptno)values(100,'tom',10);
    - 如果插入一条视图不可见,但是原表中却可见的数据称为数据污染
        insert into v_emp_10(empno,ename,deptmno)values(1001,'jim',20);
   - 通过 with check option 解决数据污染
        create view v_emp_20 as(select * from emp where deptno=20)with check option;
        insert into v_emp_20 (empno,ename,deptno)values(1001,'tom',20)//成功
        insert into v_emp_20(empno,ename,deptno)values(1002,'tom',30)//失败
    - 修改和删除视图数据(只能修改删除视图中的数据)
        update v_emp_20 set ename='jim' where ename = 'tom';
        update v_emp_20 set ename='Jim' where deptno = 10;
        delete from v_emp_20 where deptno = 10;
    - 创建或替换视图
        create or replace view v_emp_10 as(select * from emp where deptno = 10 and sal>2000);
    - 删除视图
        drop view 视图名
    - 如果创建视图的子查询中使用了别名,则对视图操作时只能使用别名
        create view v_emp_10 as(select ename as 'name' from emp where deptno = 10);
        select name from v_emp_10;//成功
        select ename from v_emp_10;//失败
    - 视图总结:
        1.视图是数据中的对象,代表一段SQL语句,可以理解为一张虚拟的表.
        2.作用:重用SQL,隐藏敏感信息
        3.分类:简单视图(创建简单视图时不使用去重,函数,分组关联查询,可以对数据进行增删改查)和复杂视图(和简单视图相反,只能对数据进行查询操作)
        4.插入数据时可能出现视图污染,通过 with check option 解决
        5.如果创建视图的子查询中使用了别名,则对视图操作时只能使用别名
        6.删除和修改只能操作视图中存在的数据
63.约束
    - 什么是约束:约束就是给表字段添加限制的条件
    - 主键约束+自增: 作用:唯一且非空
    - 非空约束: not null
        - 作用:该字段的不能为null
            create table t_null(id int,age int not null);
            insert into t_null values(1,23);//成功
            insert into t_null values(2,null);//失败
    - 唯一约束 unique
        - 作用: 该字段的值不能重复
            create table t_unique(id int,age int unique);
            insert into t_unique values(1,21);//成功
            insert into t_unique values(2,21);//失败
    - 默认约束 default
        - 作用:给字段设置默认值
            create table t_default(id int,age int default 20);
            insert into t_default(id)values(1);//默认值生效
            insert into t_default values(2,null);//默认值不生效
            insert into t_defaule values(3,30);//可以赋其他值
    - 外键约束
        - 外键:用来建立关系的字段称为外键
        - 外键约束:添加外键约束的字段,值不能为null,可以重复,但是值不能是关联表中不存在的数据
    - 如何使用外键约束
        1.创建部门表
            create table dept(id int primary key auto_increment,name varchar(10));
        2.创建员工表
            create table emp(id int primary key auto_incement,name varchar(10),dept_id int,constraint fk_dept foreign key(dept_id)references dept(id));
        - 格式: constraint 约束名称; foreign(外字段名)references 依赖的表名(依赖的字段名)
        - 测试插入数据
            insert into dept values(null,'神界'),(null,'魔界');
            insert into emp values(null,'赛利亚',1),(null,'卢克',2);
            insert into emp values(null,'卢克',3);//失败
            delete from dept where id=1;//失败
            drop table dept;//失败
    - 由于添加外键约束会影响测试效果,所以工作中很少使用,一般都是通过Java代码实现逻辑外键
64.索引
    - 什么是索引: 索引是数据中来提高查询效率的技术,类似于目录.
    - 为什么使用索引:如果不使用索引会零散的保存在磁盘块中,查询数据需要挨个遍历每一个磁盘块,直到找到数据为止,使用索引后会见磁盘块以树状结构保存,查询数据时会大大减低磁盘块的访问量,从而提高查询效率
    - 有索引就一定好吗?:如果表中的数据很少,是用索引反而会减低查询效率
    - 索引是越多越好?:不是,索引会占用储存磁盘空间,只针对查询时常用的字段创建索引
    -  如何创建索引
    -  格式: create index 索引名 on 表名(字段名(字符长度));
          create index syin on info(name);
    - 索引分类
        1.聚集索引:通过主键创建的索引称为聚集索引,聚集索引中保存数据,只要给表添加主键,则会自动创建聚集索引
        2.非聚集索引:通过非主键段创建的索引成为非聚集索引,非聚集索引 中没有数据
    - 如何查看索引
        格式: show index from 表名;
    - 删除索引
        格式: drop index 索引名 on 表名;
    - 复合索引: 通过多字段穿件的索引成为复合索引
        格式:create index 索引名 on 表名(字段1,字段2);
        create index syin on info(id,name);
    - 索引总结
        1.索引是用来提高查询效率的技术,类似目录
        2.因为索引会占用磁盘空间,所以不是越多越好
        3.因为数据量小的时候使用索引会减低查询效率所以不是有索引就一定好
        4.分类:聚集索引和非聚集索引
        5.通过多个字段创建的索引称为复合索引
65.事务
    - 数据库中执行统一业务多条SQL语句的工作单元,可以保证全部执行成功或者全部执行失败
    - 事务的ACID特性
        - ACID是保证数据库事务正确执行的四大基本要素
            1.Atomicty:原子性,最小不可拆分,保证全部成功或者全部失败
            2.Consistency:一致性,保证事务从一个一致状态到另外一个一致状态
            3.Isolation:隔离性,多个事务间互补影响
            4.Duablity:持久性,事务提交之后数据保存到数据库文件中持久生效
    - 事务相关SQL
        - 开启事务 :begin;
        - 回滚事务 :rollback;
        - 提交事务 : commit;
        - 标记事务:savepoint s1;
        - 回滚到标记事务 :rollback to s1;
66.组连接 group_concat()
    - 查询每一个部门所有员工的姓名和工资
        select deptno,group_concat(ename,'-',sal)from emp group by deptno;

 

- 如何不使用SQL语句修改字符集和端口号
    - 在mySQL的安装目录下找到my.ini配置文件,在配置文件中的[client] 下找到 port = 修改端口号, default-charset= 修改默认字符集.如果知道在哪里找到这个配置文件,可以打开mySQL终端输入 show variabels like '%data%'; data文件的路径,复制此路径粘贴到我的电脑地址栏回车,然后退一级目录就可以找到my.ini配置文件;Linux系统的配置文件名称为my.cnf

- 数据库的存储过程
    - 存储过程就是存储在数据库服务器中的一组SQL语句,通过在查询中调用一个指定的名称来执行这类SQL语句命令
    - 创建存储过程: create procedure 存储过程名(参数);
    - 存储过程体:create function 存储函数名(参数);
    - 优点:
        - 1 存储过程只在创建时进行编译,以后每次执行存储过程 不需要再重新编译,而一般SQL语句每执行一次就编译一次,因此使用存储过程可以大大提高数据执行速度
        - 2 存储过程一次创建便可以重复使用,从而可以减少数据开发人员的工作量
        - 3 安全性高,存储过程中可屏蔽底层数据库对象直接访问,使用Execute权限调用存储过程,无需拥有访问底层数据库对象的显示权限
    - 缺点: 可维护性差,可读性也差

- mySQL与oracle的区别
    - mySQL是自动增长数据类型,插入记录时不需要操作此字段,会自动获得数据值.oracle没有自动增长的类型,需要建立一个自动增长的序列号,插入记录时把序列号的值赋予此字段
    - 单引号处理:MySQL是可以使用双引号包起字符串的,oracle中只可以使用单引号包起字符串,在插入和修改字符串前必须做单引号的替换,把所有出现的一个单引号替换成两个单引号
    - 分页查询:MySQL使用的是limit; oracle使用的是rownum
    - 长字符串处理:oracle对于长字符串的处理,update insert 可以最大操作字符串长度为 <=4000的单字节
    - 日期字段处理:MySQL日期字段名有date和time; oracle只有date包含年月日时分秒信息
    - MySQL非空字段允许有null值; oracle 非空字段不允许有空内容
    - 注册驱动不同
        - MySQL driverClass:com.mysql.jdbc.Driver   url: jdbc:mysql://localhost:3306/用户名
        - oracle driverClass:oracle.jdbc.driver.OracleDriver    url:jdbc:oracle:thin:@127.0.0.1:1521:用户名
    - 整数字段类型:MySQL 整数字段类型使用 int bigint; oracle 整数字段类型使用 number


- 如何提高查询数据的速度
    - 查询时不要过多的使用通配符进行查询,要用到几列就查询几列
    - 避免使用不兼容的数据类型,例如:float和int char和varchar binary和varbinary
    - 尽量避免where句子中对字段进行函数或表达是操作,这样会导致引擎放弃使用索引而进行全表扫描
    - 避免使用 != <> ,is null ,is not null, in , not in,这样的操作符,因为这样会使系统无法使用索引,而直接搜索表中的数据
    - 尽量使用数字型字段,一部分开发人员和数据库管理员喜欢把包含数值信息的字段设计为字符型,这样会降低查询和连接性能,并且会增加存储开销,这是因为引擎在处理连接会逐个比较字符串中每个字符,对于数字型而言只需要比较一次就够了
    - 尽量避免在索引字符数据中使用非开头字母搜索,这样使得引擎无法利用索引
    - 充分利用连接条件,在某种情况下两个表不止一个连接条件,在where子句中将连接条件写完整会大大提升查询速度 


1、你熟悉的远程有哪些方法,各种方法应该怎么配置 
参考答案:
1.最简单的QQ上有,打开对话框,上边有个 “应用”图标,点击“远程协助”。 
2.系统自带的远程桌面//服务,右击我的电脑—属性,点远程,把两个够都打上去。 
3.远程协助软件,在要远程的主机安装代理程序后,即可使用远程服务。 
4.专业通信系统,即时通、 OA之类的。 
 
2、在你进行实施的过程中,公司制作的一款软件系统缺少某一项功能而且公司也明确表示不会再为系统做任何的修改或添加任何的功能,而客户也坚决要求需要这一项功能对于实施人员来说应该怎么去合理妥善处理这个问题. 
参考答案:
先看客户要求合不合理,不合理就可以坚决退还需求。如果需求合理的话,可以 
1.申请做二次开发,并且收取一定的费用,这个两边都要沟通好。 
2.第二种方法,使用第三方软件做补助。 
 
 
3、在项目实施过程中,使用者对产品提出了适合自己习惯的修改意见,但多个使用者相互矛盾,应该如何去处理 
参考答案:
对于客户提出的修改意见我们实施人员应该有自己的方案。当使用者之间意见出现不一致时,我们应当引导他们内部之间的意见统一,和客户经过沟通或确认后,找到切实可行的方案,双方认可并达成共识。 
 
4、同一个网络环境中,A电脑访问不到B电脑的共享文件。此现象可能是哪些方面所导致,怎样处理
参考答案: 
首先检查网络是否有问题,再确定是不是在一个工作组内,只有在一个工作组内才可以共享文件,然后
看有没有被防火墙阻止,最后确定文件是不是已经被共享。 
 
 
5、什么是DHCP如何快速为多台,20台,电脑安装操作系统,多台电脑如何组网 
参考答案:
1.DHCP 动态主机设置协议是一个局域网的网络协议,使用UDP协议工作主要有两个用途,给内部网络或网络服务供应商自动分配IP地址、给用户给内部网络管理员作为对所有计算机作中央管理的手
段。
2.可以通过网络硬盘克隆,过程为,在装有软驱的工作站上用一张引导盘来启动机器连接到服务器,使用 Ghost 多播服务,Multicast Server,将硬盘或分区的映像克隆到工作站,这样就实现了不拆机、安全、快速的网络硬盘克隆。 
3.多台电脑组网可以分为两个类型, ①、少于250台,可以采用用户接入层和核心接入层这二层网络结构,通过普通二层交换机与核心交换机的堆叠连接组成单位局域网以满足单位各种上网访问需求。普通电脑通过双绞线连接到普通百兆二层交换机。 
②、超过250台我们就需要通过交换机的VLAN功能将它们划分到不同的子网中。为了让两网段中的所有电脑都能实现共享上网目的,我们还需要在核心路由交换机或者双WAN端口路由器设备中对两个网关参数进行合适配置,确保各个子网中的电脑能通过局域网路由功能访问Internet网络。 
 
 
6、局域网内,一台机器不能上网,而其他机器可以。所有的机器都安装的WinXP系统且该电脑可以访问局域网内电脑,试分析原因. 
参考答案: 
可能由如下原因导致: 
1.检查有无 Microsoft网络客户端、 Microsoft网络的文件和打印机共享、 Internet协议(TCP/IP) 。 
2.检查 IP地址、网关、DNS 、网络是否连上等。 
3.查杀木马、病毒。 
 
7、如果有一个不太懂电脑的客户,你应该采取什么样的方法去教他用公司的软件产品 
参考答案: 
1.如果软件产品比较难懂,你就可以先教一些简单的。再告诉他需要再了解哪些知识来掌握这个软件。
2.如果软件产品比较简单,就可以直接一步一步的教他怎么操作,一直操作熟练就行了。 
 
8、当你觉得工作的付出和你的收入不成正比的时候你会怎么想. 
参考答案:
无论干什么工作必须干一行爱一行,脚踏实地、用心去钻研 只要真正有能力,只要有思想和技术终会出头。砖石总会发光的。接受你不能接受的,改变你能改变的。会争取到更高的薪水的。 
如果当初进来的时候公司有晋升调薪的承诺,那就看你的表现是否达到了要求,可以主动和相关领导沟
通。 
 
9、一般数据库若出现日志满了,会出现什么情况是否还能使用 
参考答案: 
数据库满了就不能使用数据库.数据库满是指数据文件达到设置的最大文件大小,没设置的时候就是最大可用磁盘空间只能执行查询,等读的操作,不能执行更改、备份等写操作,原因是任何写操作都要记录日志。
也就是说基础处于不可用的状态。 
 
10、触发器的作用是什么?
参考答案: 
触发器是针对数据表库的特殊的存储过程当这个表发生了 Insert、Update或Delete操作时,数据库就会自动执行触发器所定义的SQL语句,从而确保对数据的处理必须符合这些SQL语句所定义的规则。 
 
11、系统启动后不能连接数据库可能是哪些方面的原因
参考答案:
1.和数据库有关的服务没启动
2.防火墙可能阻挡了数据库的端口
3.如数据库可以启动而登陆不了,可能是密码错误或连接参数配置错误
4.数据库文件已被破坏或不存在
 
12、你认为客户服务的重点是什么 
参考答案:
随着市场的竞争进一步加剧,服务已经成为企业核心竞争力的要素之一,服务的重点是沟通沟通可以消除客户的误会和不满,沟通可以提高客户的感知度。因此我认为我们客户服务管理工作就应该从做好沟通的管理开始。 
自己一定要理解服务,理解服务能干什么,能做到什么结合公司的业务能给客户提供什么服务。服务过程中是否能给客户提供优秀的服务,倾听客户的意见持续改进服务方式。尽量在事件发生之前避免或杜绝客户的投诉投诉发生后认真处理。 
 
13、说明静态路由和动态路由的区别 
参考答案: 
静态路由:就是由管理员在路由器中手工设置的固定的路由信息静态路由不能对网络的改变做出反映一般用于规模不大、拓扑结构固定的网络中其优点是设置简单、高效在所有路由中静态路由优先级最高 当动态路由与静态路由发生冲突时以静态路由为准。 
动态路由:就是由网络中的路由器之间互相通信传递路由信息利用收到的路由信息更新路由表的过程
它能实时地适应网络结构的变化。主要用于规模大、拓扑结构复杂的网络。 数据库部分 已知表  

Create Table Department  ( dept_id varchar(2) not null,  -- 部门编号  dept_name varchar(20) not null, -- 部门名称 
dept_leader varchar(10) –部门经理 ); 
Create Table Personnel ( id varchar(4) not null, --员工号 name varchar(10) not null, --姓名 dept_id varchar(2) not null, --部门编号 age integer, --年龄 gzsj date, --参加工作时间 technical_post varchar(10), --职称 salary integer –薪水 ); 
1.写出表Department增加一条记录 和 更新一条记录的 SQL语句  
增加记录值 (‘12’, ‘研发部’, ‘张三’)  更新 dept_id=’12’的记录 (‘12’, ‘研发部’, ‘张三新’) ; 
参考答案: 
增加记录:Insert into Department(dept_id,dept_name,dept_leader)  values (‘12’,’研发部’,’张三’) 
更新记录:Update Department  set  dept_leader=’张三新’  where  dept_id=’12’; 
 
 
2. 需要给表Department增加一列字段notes长度为10的字符串默认值为‘0’ , 请写出相关SQL语句 
参考答案:  
Alter  table  Department  add  notes varchar(10) default 0; 
 
3.查找工资大于2000元的员工记录并按员工号id升序排列 
参考答案: 
Select  name  from  Personnel  where  salary integer>2000  order  by  id; 
 
4.查找工资大于2000元的员工所在部门、部门编号、部门经理、员工名称 
参考答案: 
Select  dept_name,dept_id,dept_leader from Department where dept_id in(select  dept_id  from Personnel  
where  salary integer>2000 ); 
 
5.查找张三和李四所在部门所有人员的姓名 
参考答案: 
Select  name  from  Personnel  where  name=’张三’  and  name=’李四’; 
 
6、查看每个部门的部门经理和部门人数按部门人数排序 
参考答案: 
Select d.dept_leader,(select count(*) from Personnel p where d.dept_id=p.dept_id) from Department d,personnel p 
group by d.dept_id order by co; 
 
7、删除表Department中的所有记录 
参考答案: 
Delete  from  Department; 
 
8、删除表Department 
参考答案: 
Drop  table  Department; 
 
9、解释Oracle数据库、数据文件、表空间  
参考答案: 
1.Oracle数据库Oracle Database又名Oracle RDBMS或简称Oracle。是甲骨文公司的一款关系数据库管理系统。  
2.数据文件每一个ORACLE数据库有一个或多个物理的数据文件(data file)。一个数据库的数据文件包含全部数据库数据。逻辑数据库结构(如表、索引)的数据物理地存储在数据库的数据文件中。 
 
3.表空间表空间是数据库的逻辑划分,一个表空间只能属于一个数据库。所有的数据库对象都存放在指定的表空间中。但主要存放的是表所以称作表空间。 
 
10、表、视图的区别存储过程、函数的区别 
参考答案:
1.表和视图的区别
表是数据库中的主要结构它总是表示单个的、特定的集合。每个表至少包含一个字段即一个主键他唯一地标识表的每条记录。  
视图是由来自数据库中的一个或多个表或多个表的字段所组成的一个虚拟的表。实际上它自身不存储任何数据存储在数据库中的有关视图的唯一信息几句是它的结构。 
 
2.存储过程、函数的区别 
存储过程是用户定义的一系列sql语句的集合涉及特定表或其它对象的任务用户可以调用存储过程函通常是数据库已定义的方法它接收参数并返回某种类型的值并且不涉及特定用户表。


            

      
数据库部分
1、用两种方式根据部门号从高到低,工资从低到高列出每个员工的信息。
employee: eid,ename,salary,deptid;
 select * from employee order by deptid desc,salary
2、列出各个部门中工资高于本部门的平均工资的员工数和部门号,并按部门号排序
创建表:
    - create table employee921(id int primary key auto_increment,name varchar(50),salary bigint,deptid int);
 
插入实验数据:
insert into employee921 values(null,'zs',1000,1),(null,'ls',1100,1),
(null,'ww',1100,1),(null,'zl',900,1),(null,'zl',1000,2),(null,'zl',900,2),(null,'zl',1000,2), (null,'zl',1100,2);
 
编写sql语句:
 
select avg(salary) from employee921 group by deptid;
Select employee921.id,employee921.name,employee921.salary,employee921.deptid tid from employee921 where salary > (select avg(salary) from employee921 where  deptid = tid);
   效率低的一个语句,仅供学习参考使用(在group by之后不能使用where,只能使用having,在group by之前可以使用where,即表示对过滤后的结果分组):
    select employee921.id,employee921.name,employee921.salary,employee921.deptid tid from  employee921 where salary > (select avg(salary) from employee921 group by deptid having deptid = tid);
    select count(*) ,tid from (select employee921.id,employee921.name,employee921.salary,employee921.deptid tid from employee921 where salary >(select avg(salary) from employee921 where  deptid = tid)) as t group by tid ;
 
另外一种方式:关联查询
    select a.ename,a.salary,a.deptid from emp a,(select deptd,avg(salary) avgsal from emp group by deptid ) b where a.deptid=b.deptid and a.salary>b.avgsal
3、存储过程与触发器必须讲,经常被面试到?
    create procedure insert_Student (_name varchar(50),_age int ,out _id int)begin insert into student value(null,_name,_age);select max(stuId) into _id from end;call insert_Student('wfz',23,@id);select @id;
 
    create trigger update_Student BEFORE update on student FOR EACH ROW 
    select * from student;
触发器不允许返回结果
 
    create trigger update_Student BEFORE update on student FOR EACH ROW  
    insert into  student value(null,'zxx',28);
mysql的触发器目前不能对当前表进行操作
 
    create trigger update_Student BEFORE update on student FOR EACH ROW  
    delete from articles  where id=8;
这个例子不是很好,最好是用删除一个用户时,顺带删除该用户的所有帖子
这里要注意使用OLD.id
 
触发器用处还是很多的,比如校内网、开心网、Facebook,你发一个日志,自动通知好友,其实就是在增加日志时做一个后触发,再向通知表中写入条目。因为触发器效率高。而UCH没有用触发器,效率和数据处理能力都很低。
存储过程的实验步骤:
mysql> delimiter |
mysql> create procedure insertArticle_Procedure (pTitle varchar(50),pBid int,out
 pId int)
    -> begin
    -> insert into article1 value(null,pTitle,pBid);
    -> select max(id) into pId from article1;
    -> end;
    -> |
Query OK, 0 rows affected (0.05 sec)
 
mysql> call insertArticle_Procedure('传智播客',1,@pid);
    -> |
Query OK, 0 rows affected (0.00 sec)
 
mysql> delimiter ;
mysql> select @pid;
+------+
| @pid |
+------+
| 3    |
+------+
1 row in set (0.00 sec)
 
mysql> select * from article1;
+----+--------------+------+
| id | title        | bid  |
+----+--------------+------+
| 1  | test         | 1    |
| 2  | chuanzhiboke | 1    |
| 3  | 传智播客     | 1    |
+----+--------------+------+
3 rows in set (0.00 sec)
 
触发器的实验步骤:
create table board1(id int primary key auto_increment,name varchar(50),ar
ticleCount int);
 
create table article1(id int primary key auto_increment,title varchar(50)
,bid int references board1(id));
 
delimiter |
 
create trigger insertArticle_Trigger after insert on article1 for each ro
w begin
    -> update board1 set articleCount=articleCount+1 where id= NEW.bid;
    -> end;
    -> |
 
delimiter ;
 
insert into board1 value (null,'test',0);
 
insert into article1 value(null,'test',1);
还有,每插入一个帖子,都希望将版面表中的最后发帖时间,帖子总数字段进行同步更新,用触发器做效率就很高。下次课设计这样一个案例,写触发器时,对于最后发帖时间可能需要用declare方式声明一个变量,或者是用NEW.posttime来生成。
4数据库三范式是什么?
第一范式(1NF):字段具有原子性,不可再分。所有关系型数据库系统都满足第一范式)
      数据库表中的字段都是单一属性的,不可再分。例如,姓名字段,其中的姓和名必须作为一个整体,无法区分哪部分是姓,哪部分是名,如果要区分出姓和名,必须设计成两个独立的字段。
 
  第二范式(2NF):
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。
要求数据库表中的每个实例或行必须可以被惟一地区分。通常需要为表加上一个列,以存储各个实例的惟一标识。这个惟一属性列被称为主关键字或主键。
 
第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是非主属性非部分依赖于主关键字。
  
 第三范式的要求如下: 
满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。
所以第三范式具有如下特征:
         1,每一列只有一个值 
         2,每一行都能区分。 
         3,每一个表都不包含其他表已经包含的非主关键字信息。
例如,帖子表中只能出现发帖人的id,而不能出现发帖人的id,还同时出现发帖人姓名,否则,只要出现同一发帖人id的所有记录,它们中的姓名部分都必须严格保持一致,这就是数据冗余。
5说出一些数据库优化方面的经验?
用PreparedStatement 一般来说比Statement性能高:一个sql 发给服务器去执行,涉及步骤:语法检查、语义分析,编译,缓存
“inert into user values(1,1,1)”-à二进制
“inert into user values(2,2,2)”-à二进制
“inert into user values(?,?,?)”-à二进制
 
 
 
有外键约束会影响插入和删除性能,如果程序能够保证数据的完整性,那在设计数据库时就去掉外键。(比喻:就好比免检产品,就是为了提高效率,充分相信产品的制造商)
(对于hibernate来说,就应该有一个变化:empleyee->Deptment对象,现在设计时就成了employeeàdeptid)
 
看mysql帮助文档子查询章节的最后部分,例如,根据扫描的原理,下面的子查询语句要比第二条关联查询的效率高:
1.  select e.name,e.salary where e.managerid=(select id from employee where name='zxx');
 
2.   select e.name,e.salary,m.name,m.salary from employees e,employees m where
 e.managerid = m.id and m.name='zxx';
 
表中允许适当冗余,譬如,主题帖的回复数量和最后回复时间等
将姓名和密码单独从用户表中独立出来。这可以是非常好的一对一的案例哟!
 
sql语句全部大写,特别是列名和表名都大写。特别是sql命令的缓存功能,更加需要统一大小写,sql语句à发给oracle服务器à语法检查和编译成为内部指令à缓存和执行指令。根据缓存的特点,不要拼凑条件,而是用?和PreparedStatment
 
还有索引对查询性能的改进也是值得关注的。
 
备注:下面是关于性能的讨论举例
 
4航班 3个城市
 
m*n
 
select * from flight,city where flight.startcityid=city.cityid and city.name='beijing';
 
m + n
 
 
select * from flight where startcityid = (select cityid from city where cityname='beijing');
 
select flight.id,'beijing',flight.flightTime from flight where startcityid = (select cityid from city where cityname='beijing')
6、union和union all有什么不同?
假设我们有一个表Student,包括以下字段与数据:
drop table student;
create table student
(
id int primary key,
name nvarchar2(50) not null,
score number not null
);
insert into student values(1,'Aaron',78);
insert into student values(2,'Bill',76);
insert into student values(3,'Cindy',89);
insert into student values(4,'Damon',90);
insert into student values(5,'Ella',73);
insert into student values(6,'Frado',61);
insert into student values(7,'Gill',99);
insert into student values(8,'Hellen',56);
insert into student values(9,'Ivan',93);
insert into student values(10,'Jay',90);
commit;
Union和Union All的区别。 
select *
from student
where id < 4
union
select *
from student
where id > 2 and id < 6
结果将是
1    Aaron    78
2    Bill    76
3    Cindy    89
4    Damon    90
5    Ella    73
如果换成Union All连接两个结果集,则返回结果是:
1    Aaron    78
2    Bill    76
3    Cindy    89
3    Cindy    89
4    Damon    90
5    Ella    73
可以看到,Union和Union All的区别之一在于对重复结果的处理。
 
UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。实际大部分应用中是不会产生重复的记录,最常见的是过程表与历史表UNION。如:
select * from gc_dfys
union
select * from ls_jg_dfys
  这个SQL在运行时先取出两个表的结果,再用排序空间进行排序删除重复的记录,最后返回结果集,如果表数据量大的话可能会导致用磁盘进行排序。
 而UNION ALL只是简单的将两个结果合并后就返回。这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。
 从效率上说,UNION ALL 要比UNION快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据的话,那么就使用UNION ALL,
7.分页语句
取出sql表中第31到40的记录(以自动增长ID为主键)
sql server方案1:
      select top 10 * from t where id not in (select top 30 id from t order by id ) orde by id
sql server方案2:
      select top 10 * from t where id in (select top 40 id from t order by id) order by id desc
 
mysql方案:select * from t order by id limit 30,10
 
oracle方案:select * from (select rownum r,* from t where r<=40) where r>30
 
--------------------待整理进去的内容-------------------------------------
pageSize=20;
pageNo = 5;
 
1.分页技术1(直接利用sql语句进行分页,效率最高和最推荐的)
 
mysql:sql = "select * from articles limit " + (pageNo-1)*pageSize + "," + pageSize;
oracle: sql = "select * from " +
                                                "(select rownum r,* from " +
                                                      "(select * from articles order by postime desc)" +
                                                "where rownum<= " + pageNo*pageSize +") tmp " +
                                          "where r>" + (pageNo-1)*pageSize;
注释:第7行保证rownum的顺序是确定的,因为oracle的索引会造成rownum返回不同的值
简洋提示:没有order by时,rownum按顺序输出,一旦有了order by,rownum不按顺序输出了,这说明rownum是排序前的编号。如果对order by从句中的字段建立了索引,那么,rownum也是按顺序输出的,因为这时候生成原始的查询结果集时会参照索引表的顺序来构建。
 
sqlserver:sql = "select top 10 * from id not id(select top " + (pageNo-1)*pageSize + "id from articles)"
 
DataSource ds = new InitialContext().lookup(jndiurl);
Connection cn = ds.getConnection();
//"select * from user where id=?"  --->binary directive
PreparedStatement pstmt = cn.prepareSatement(sql);
ResultSet rs = pstmt.executeQuery()
while(rs.next())
{
      out.println(rs.getString(1));
}
 
2.不可滚动的游标
pageSize=20;
pageNo = 5;
cn = null
stmt = null;
rs = null;
try
{
sqlserver:sql = "select  * from articles";
 
DataSource ds = new InitialContext().lookup(jndiurl);
Connection cn = ds.getConnection();
//"select * from user where id=?"  --->binary directive
PreparedStatement pstmt = cn.prepareSatement(sql);
ResultSet rs = pstmt.executeQuery()
for(int j=0;j<(pageNo-1)*pageSize;j++)
{
      rs.next();
}
 
int i=0;
 
while(rs.next() && i<10)
{
      i++;
      out.println(rs.getString(1));
}
}
cacth(){}
finnaly
{
      if(rs!=null)try{rs.close();}catch(Exception e){}
      if(stm.........
      if(cn............
}
 
3.可滚动的游标
pageSize=20;
pageNo = 5;
cn = null
stmt = null;
rs = null;
try
{
sqlserver:sql = "select  * from articles";
 
DataSource ds = new InitialContext().lookup(jndiurl);
Connection cn = ds.getConnection();
//"select * from user where id=?"  --->binary directive
PreparedStatement pstmt = cn.prepareSatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,...);
//根据上面这行代码的异常SQLFeatureNotSupportedException,就可判断驱动是否支持可滚动游标
 
ResultSet rs = pstmt.executeQuery()
rs.absolute((pageNo-1)*pageSize)
int i=0;
while(rs.next() && i<10)
{
      i++;
      out.println(rs.getString(1));
}
}
cacth(){}
finnaly
{
      if(rs!=null)try{rs.close();}catch(Exception e){}
      if(stm.........
      if(cn............
}
8.用一条SQL语句查询出每门课都大于80分的学生姓名  
name   kecheng   fenshu 
张三     语文       81
张三     数学       75
李四     语文       76
李四     数学       90
王五     语文       81
王五     数学       100
王五     英语       90
准备数据的sql代码:
create table score(id int primary key auto_increment,name varchar(20),subject varchar(20),score int);
insert into score values 
(null,'张三','语文',81),
(null,'张三','数学',75),
(null,'李四','语文',76),
(null,'李四','数学',90),
(null,'王五','语文',81),
(null,'王五','数学',100),
(null,'王五 ','英语',90);
 
提示:当百思不得其解时,请理想思维,把小变成大做,把大变成小做,
 
答案:
A: select distinct name from score  where  name not in (select distinct name from score where score<=80)
 
B:select distince name t1 from score where 80< all (select score from score where name=t1);
9.所有部门之间的比赛组合
一个叫department的表,里面只有一个字段name,一共有4条纪录,分别是a,b,c,d,对应四个球对,现在四个球对进行比赛,用一条sql语句显示所有可能的比赛组合.
答:select a.name, b.name 
from team a, team b 
where a.name < b.name
10.每个月份的发生额都比101科目多的科目
请用SQL语句实现:从TestDB数据表中查询出所有月份的发生额都比101科目相应月份的发生额高的科目。请注意:TestDB中有很多科目,都有1-12月份的发生额。
AccID:科目代码,Occmonth:发生额月份,DebitOccur:发生额。
数据库名:JcyAudit,数据集:Select * from TestDB
准备数据的sql代码:
drop table if exists TestDB;
create table TestDB(id int primary key auto_increment,AccID varchar(20), Occmonth date, DebitOccur bigint);
insert into TestDB values 
(null,'101','1988-1-1',100),
(null,'101','1988-2-1',110),
(null,'101','1988-3-1',120),
(null,'101','1988-4-1',100),
(null,'101','1988-5-1',100),
(null,'101','1988-6-1',100),
(null,'101','1988-7-1',100),
(null,'101','1988-8-1',100);
--复制上面的数据,故意把第一个月份的发生额数字改小一点
insert into TestDB values 
(null,'102','1988-1-1',90),
(null,'102','1988-2-1',110),
(null,'102','1988-3-1',120),
(null,'102','1988-4-1',100),
(null,'102','1988-5-1',100),
(null,'102','1988-6-1',100),
(null,'102','1988-7-1',100),
(null,'102','1988-8-1',100);
--复制最上面的数据,故意把所有发生额数字改大一点
insert into TestDB values 
(null,'103','1988-1-1',150),
(null,'103','1988-2-1',160),
(null,'103','1988-3-1',180),
(null,'103','1988-4-1',120),
(null,'103','1988-5-1',120),
(null,'103','1988-6-1',120),
(null,'103','1988-7-1',120),
(null,'103','1988-8-1',120);
--复制最上面的数据,故意把所有发生额数字改大一点
insert into TestDB values 
(null,'104','1988-1-1',130),
(null,'104','1988-2-1',130),
(null,'104','1988-3-1',140),
(null,'104','1988-4-1',150),
(null,'104','1988-5-1',160),
(null,'104','1988-6-1',170),
(null,'104','1988-7-1',180),
(null,'104','1988-8-1',140);
--复制最上面的数据,故意把第二个月份的发生额数字改小一点
insert into TestDB values 
(null,'105','1988-1-1',100),
(null,'105','1988-2-1',80),
(null,'105','1988-3-1',120),
(null,'105','1988-4-1',100),
(null,'105','1988-5-1',100),
(null,'105','1988-6-1',100),
(null,'105','1988-7-1',100),
(null,'105','1988-8-1',100);
答案:
select distinct AccID from TestDB 
where AccID not in 
      (select TestDB.AccIDfrom TestDB,
             (select * from TestDB where AccID='101') as db101 
      where TestDB.Occmonth=db101.Occmonth and TestDB.DebitOccur<=db101.DebitOccur
      );
11.统计每年每月的信息
year  month amount
1991   1     1.1
1991   2     1.2
1991   3     1.3
1991   4     1.4
1992   1     2.1
1992   2     2.2
1992   3     2.3
1992   4     2.4
查成这样一个结果
year m1  m2  m3  m4
1991 1.1 1.2 1.3 1.4
1992 2.1 2.2 2.3 2.4 
提示:这个与工资条非常类似,与学生的科目成绩也很相似。
 
准备sql语句:
drop table if exists sales;
create table sales(id int auto_increment primary key,year varchar(10), month varchar(10), amount float(2,1));
insert into sales values
(null,'1991','1',1.1),
(null,'1991','2',1.2),
(null,'1991','3',1.3),
(null,'1991','4',1.4),
(null,'1992','1',2.1),
(null,'1992','2',2.2),
(null,'1992','3',2.3),
(null,'1992','4',2.4);

答案一、
select sales.year ,
(select t.amount from sales t where t.month='1' and t.year= sales.year) '1',
(select t.amount from sales t where t.month='1' and t.year= sales.year) '2',
(select t.amount from sales t where t.month='1' and t.year= sales.year) '3',
(select t.amount from sales t where t.month='1' and t.year= sales.year) as '4' 
from sales  group by year;
12.显示文章标题,发帖人、最后回复时间
表:id,title,postuser,postdate,parentid
准备sql语句:
drop table if exists articles;
create table articles(id int auto_increment primary key,title varchar(50), postuser varchar(10), postdate datetime,parentid int references articles(id));
insert into articles values
(null,'第一条','张三','1998-10-10 12:32:32',null),
(null,'第二条','张三','1998-10-10 12:34:32',null),
(null,'第一条回复1','李四','1998-10-10 12:35:32',1),
(null,'第二条回复1','李四','1998-10-10 12:36:32',2),
(null,'第一条回复2','王五','1998-10-10 12:37:32',1),
(null,'第一条回复3','李四','1998-10-10 12:38:32',1),
(null,'第二条回复2','李四','1998-10-10 12:39:32',2),
(null,'第一条回复4','王五','1998-10-10 12:39:40',1);
 
答案:
select a.title,a.postuser,
      (select max(postdate) from articles where parentid=a.id) reply 
from articles a where a.parentid is null;
 
注释:子查询可以用在选择列中,也可用于where的比较条件中,还可以用于from从句中。
13.删除除了id号不同,其他都相同的学生冗余信息
2.学生表 如下:
id号   学号   姓名 课程编号课程名称 分数
1        2005001  张三  0001      数学    69
2        2005002  李四  0001      数学    89
3        2005001  张三  0001      数学    69
A: delete from tablename where id号 not in(select min(id号) from tablename group by 学号,姓名,课程编号,课程名称,分数)
实验:
create table student2(id int auto_increment primary key,code varchar(20),name varchar(20));
insert into student2 values(null,'2005001','张三'),(null,'2005002','李四'),(null,'2005001','张三');
 
//如下语句,mysql报告错误,可能删除依赖后面统计语句,而删除又导致统计语句结果不一致。
 
delete from student2 where id not in(select min(id) from student2 group by name);
//但是,如下语句没有问题:
select *  from student2 where id not in(select min(id) from student2 group by name);
//于是,我想先把分组的结果做成虚表,然后从虚表中选出结果,最后再将结果作为删除的条件数据。
delete from student2 where id not in(select mid from (select min(id) mid
from student2 group by name) as t);
或者:
delete from student2 where id not in(select min(id) from (select * from s
tudent2) as t group by t.name);
14.航空网的几个航班查询题:
表结构如下:
flight{flightID,StartCityID ,endCityID,StartTime}
city{cityID, CityName)
实验环境:
create table city(cityID int auto_increment primary key,cityName varchar(20));
create table flight (flightID int auto_increment primary key,
      StartCityID int references city(cityID),
      endCityID  int references city(cityID),
      StartTime timestamp); 
//航班本来应该没有日期部分才好,但是下面的题目当中涉及到了日期
insert into city values(null,'北京'),(null,'上海'),(null,'广州');
insert into flight values
      (null,1,2,'9:37:23'),(null,1,3,'9:37:23'),(null,1,2,'10:37:23'),(null,2,3,'10:37:23');
 
 
1、查询起飞城市是北京的所有航班,按到达城市的名字排序
 
 
参与运算的列是我起码能够显示出来的那些列,但最终我不一定把它们显示出来。各个表组合出来的中间结果字段中必须包含所有运算的字段。
 
  select  * from flight f,city c 
      where f.endcityid = c.cityid and startcityid = 
      (select c1.cityid from city c1 where c1.cityname = "北京")
      order by c.cityname asc;
 
mysql> select flight.flightid,'北京' startcity, e.cityname from flight,city e wh
ere flight.endcityid=e.cityid and flight.startcityid=(select cityid from city wh
ere cityname='北京');
 
mysql> select flight.flightid,s.cityname,e.cityname from flight,city s,city e wh
ere flight.startcityid=s.cityid and s.cityname='北京' and flight.endCityId=e.cit
yID order by e.cityName desc;
 
 
2、查询北京到上海的所有航班纪录(起飞城市,到达城市,起飞时间,航班号)
select c1.CityName,c2.CityName,f.StartTime,f.flightID
from city c1,city c2,flight f
where f.StartCityID=c1.cityID 
and f.endCityID=c2.cityID
and c1.cityName='北京'
and c2.cityName='上海'
3、查询具体某一天(2005-5-8)的北京到上海的的航班次数
select count(*) from 
(select c1.CityName,c2.CityName,f.StartTime,f.flightID
from city c1,city c2,flight f
where f.StartCityID=c1.cityID 
and f.endCityID=c2.cityID
and c1.cityName='北京'
and c2.cityName='上海'
and 查帮助获得的某个日期处理函数(startTime) like '2005-5-8%'
 
mysql中提取日期部分进行比较的示例代码如下:
select * from flight where date_format(starttime,'%Y-%m-%d')='1998-01-02'
15.查出比经理薪水还高的员工信息:
Drop table if not exists employees;
create table employees(id int primary key auto_increment,name varchar(50)
,salary int,managerid int references employees(id));
insert into employees values (null,' lhm',10000,null), (null,' zxx',15000,1
),(null,'flx',9000,1),(null,'tg',10000,2),(null,'wzg',10000,3);
 
Wzg大于flx,lhm大于zxx
 
解题思路:
     根据sql语句的查询特点,是逐行进行运算,不可能两行同时参与运算。
涉及了员工薪水和经理薪水,所有,一行记录要同时包含两个薪水,所有想到要把这个表自关联组合一下。
     首先要组合出一个包含有各个员工及该员工的经理信息的长记录,譬如,左半部分是员工,右半部分是经理。而迪卡尔积会组合出很多垃圾信息,先去除这些垃圾信息。
 
select e.* from employees e,employees m where e.managerid=m.id and e.sala
ry>m.salary;
16、求出小于45岁的各个老师所带的大于12岁的学生人数
数据库中有3个表 teacher 表,student表,tea_stu关系表。 
teacher 表 teaID name age 
student 表 stuID name age 
teacher_student表 teaID stuID 
要求用一条sql查询出这样的结果 
1.显示的字段要有老师name, age 每个老师所带的学生人数 
2 只列出老师age为40以下,学生age为12以上的记录
预备知识:
      1.sql语句是对每一条记录依次处理,条件为真则执行动作(select,insert,delete,update)
       2.只要是迪卡尔积,就会产生“垃圾”信息,所以,只要迪卡尔积了,我们首先就要想到清除“垃圾”信息
实验准备:
        drop table if exists tea_stu;
        drop table if exists teacher;
        drop table if exists student;
      create table teacher(teaID int primary key,name varchar(50),age int);
      create table student(stuID int primary key,name varchar(50),age int);
      create table tea_stu(teaID int references teacher(teaID),stuID int references student(stuID));
insert into teacher values(1,'zxx',45), (2,'lhm',25) , (3,'wzg',26) , (4,'tg',27);
insert into student values(1,'wy',11), (2,'dh',25) , (3,'ysq',26) , (4,'mxc',27);
insert into tea_stu values(1,1), (1,2), (1,3);
insert into tea_stu values(2,2), (2,3), (2,4);
 insert into tea_stu values(3,3), (3,4), (3,1);
insert into tea_stu values(4,4), (4,1), (4,2) , (4,3);
 
结果:2à3,3à2,4à3
 
解题思路:(真实面试答题时,也要写出每个分析步骤,如果纸张不够,就找别人要)
1要会统计分组信息,统计信息放在中间表中:
select teaid,count(*) from tea_stu group by teaid;
 
2接着其实应该是筛除掉小于12岁的学生,然后再进行统计,中间表必须与student关联才能得到12岁以下学生和把该学生记录从中间表中剔除,代码是:
select tea_stu.teaid,count(*) total from student,tea_stu 
where student.stuid=tea_stu.stuid and student.age>12 group by tea_stu.teaid
 
3.接着把上面的结果做成虚表与teacher进行关联,并筛除大于45的老师
select teacher.teaid,teacher.name,total from teacher ,(select tea_stu.tea
id,count(*) total from student,tea_stu where student.stuid=tea_stu.stuid and stu
dent.age>12 group by tea_stu.teaid) as tea_stu2 where teacher.teaid=tea_stu2.tea
id and teacher.age<45;
17.求出发帖最多的人:
select authorid,count(*) total from articles 
group by authorid 
having total=
(select max(total2) from (select count(*) total2 from articles group by authorid) as t);
 
select t.authorid,max(t.total) from
(select authorid,count(*) total from articles )as t
这条语句不行,因为max只有一列,不能与其他列混淆。
 
select authorid,count(*) total from articles 
group by authorid having total=max(total)也不行。
18、一个用户表中有一个积分字段,假如数据库中有100多万个用户,若要在每年第一天凌晨将积分清零,你将考虑什么,你将想什么办法解决?
alter table drop column score;
alter table add colunm score int;
可能会很快,但是需要试验,试验不能拿真实的环境来操刀,并且要注意,
这样的操作时无法回滚的,在我的印象中,只有inert update delete等DML语句才能回滚,
对于create table,drop table ,alter table等DDL语句是不能回滚。
 
 
解决方案一,update user set score=0; 
解决方案二,假设上面的代码要执行好长时间,超出我们的容忍范围,那我就alter table user drop column score;alter table user add column score int。
 
下面代码实现每年的那个凌晨时刻进行清零。
Runnable runnable = 
      new Runnable(){
            public void run(){
                  clearDb();
                  schedule(this,new Date(new Date().getYear()+1,0,0));
                  }           
                  };
 
schedule(runnable,
      new Date(new Date().getYear()+1,0,1));
19、一个用户具有多个角色,请查询出该表中具有该用户的所有角色的其他用户。
select count(*) as num,tb.id 
from 
 tb,
 (select role from tb where id=xxx) as t1
where
 tb.role = t1.role and tb.id != t1.id
group by tb.id 
having 
      num = select count(role) from tb where id=xxx;
20. xxx公司的sql面试
Table EMPLOYEES Structure:
EMPLOYEE_ID      NUMBER        Primary Key,
FIRST_NAME       VARCHAR2(25),
LAST_NAME       VARCHAR2(25),
Salary number(8,2),
HiredDate DATE,
Departmentid number(2)
Table Departments Structure:
Departmentid number(2)        Primary Key,
DepartmentName  VARCHAR2(25).
 
 (2)基于上述EMPLOYEES表写出查询:写出雇用日期在今年的,或者工资在[1000,2000]之间的,或者员工姓名(last_name)以’Obama’打头的所有员工,列出这些员工的全部个人信息。(4分)
select * from employees 
where Year(hiredDate) = Year(date()) 
      or (salary between 1000 and 200)
      or left(last_name,3)='abc';
 
(3) 基于上述EMPLOYEES表写出查询:查出部门平均工资大于1800元的部门的所有员工,列出这些员工的全部个人信息。(4分)
mysql> select id,name,salary,deptid did from employee1 where (select avg(salary)
 from employee1 where deptid = did) > 1800;
 
(4) 基于上述EMPLOYEES表写出查询:查出个人工资高于其所在部门平均工资的员工,列出这些员工的全部个人信息及该员工工资高出部门平均工资百分比。(5分)
select employee1.*,(employee1.salary-t.avgSalary)*100/employee1.salary 
from employee1,
      (select deptid,avg(salary) avgSalary from employee1 group by deptid) as t
where employee1.deptid = t.deptid and employee1.salary>t.avgSalary;
21、注册Jdbc驱动程序的三种方式
22、用JDBC如何调用存储过程
代码如下:
package com.huawei.interview.lym;
 
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;
 
public class JdbcTest {
 
      /**
       * @param args
       */
      public static void main(String[] args) {
            // TODO Auto-generated method stub
            Connection cn = null;
            CallableStatement cstmt = null;           
            try {
                  //这里最好不要这么干,因为驱动名写死在程序中了
                  Class.forName("com.mysql.jdbc.Driver");
                  //实际项目中,这里应用DataSource数据,如果用框架,
                  //这个数据源不需要我们编码创建,我们只需Datasource ds = context.lookup()
                  //cn = ds.getConnection();                
                  cn = DriverManager.getConnection("jdbc:mysql:///test","root","root");
                  cstmt = cn.prepareCall("{call insert_Student(?,?,?)}");
                  cstmt.registerOutParameter(3,Types.INTEGER);
                  cstmt.setString(1, "wangwu");
                  cstmt.setInt(2, 25);
                  cstmt.execute();
                  //get第几个,不同的数据库不一样,建议不写
                  System.out.println(cstmt.getString(3));
            } catch (Exception e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
            }
            finally
            {
 
                  /*try{cstmt.close();}catch(Exception e){}
                  try{cn.close();}catch(Exception e){}*/
                  try {
                        if(cstmt != null)
                              cstmt.close();
                        if(cn != null)                      
                              cn.close();
                  } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                  }
            }
      }
23、JDBC中的PreparedStatement相比Statement的好处
答:一个sql命令发给服务器去执行的步骤为:语法检查,语义分析,编译成内部指令,缓存指令,执行指令等过程。
select * from student where id =3----缓存--àxxxxx二进制命令
select * from student where id =3----直接取-àxxxxx二进制命令
select * from student where id =4--- -à会怎么干?
如果当初是select * from student where id =?--- -à又会怎么干?
 上面说的是性能提高
可以防止sql注入。
24. 写一个用jdbc连接并访问oracle数据的程序代码
25、Class.forName的作用?为什么要用? 
答:按参数中指定的字符串形式的类名去搜索并加载相应的类,如果该类字节码已经被加载过,则返回代表该字节码的Class实例对象,否则,按类加载器的委托机制去搜索和加载该类,如果所有的类加载器都无法加载到该类,则抛出ClassNotFoundException。加载完这个Class字节码后,接着就可以使用Class字节码的newInstance方法去创建该类的实例对象了。
有时候,我们程序中所有使用的具体类名在设计时(即开发时)无法确定,只有程序运行时才能确定,这时候就需要使用Class.forName去动态加载该类,这个类名通常是在配置文件中配置的,例如,spring的ioc中每次依赖注入的具体类就是这样配置的,jdbc的驱动类名通常也是通过配置文件来配置的,以便在产品交付使用后不用修改源程序就可以更换驱动类名。
26、大数据量下的分页解决方法。
答:最好的办法是利用sql语句进行分页,这样每次查询出的结果集中就只包含某页的数据内容。再sql语句无法实现分页的情况下,可以考虑对大的结果集通过游标定位方式来获取某页的数据。
sql语句分页,不同的数据库下的分页方案各不一样,下面是主流的三种数据库的分页sql:
sql server:
      String sql = 
      "select top " + pageSize + " * from students where id not in" +
 
 "(select top " + pageSize * (pageNumber-1) + " id from students order by id)" + 
 
 "order by id";
 
mysql:
  
      String sql = 
      "select * from students order by id limit " + pageSize*(pageNumber-1) + "," + pageSize;
      
oracle:
 
      String sql = 
27、说出数据连接池的工作机制是什么? 
J2EE服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接。 
实现方式,返回的Connection是原始Connection的代理,代理Connection的close方法不是真正关连接,而是把它代理的Connection对象还回到连接池中。

28、为什么要用 ORM?  和 JDBC 有何不一样? 
orm是一种思想,就是把object转变成数据库中的记录,或者把数据库中的记录转变成objecdt,我们可以用jdbc来实现这种思想,其实,如果我们的项目是严格按照oop方式编写的话,我们的jdbc程序不管是有意还是无意,就已经在实现orm的工作了。
现在有许多orm工具,它们底层调用jdbc来实现了orm工作,我们直接使用这些工具,就省去了直接使用jdbc的繁琐细节,提高了开发效率,现在用的较多的orm工具是hibernate。也听说一些其他orm工具,如toplink,ojb等。 
 

     
        
           

猜你喜欢

转载自blog.csdn.net/weixin_43062870/article/details/86559275