牛客网-数据库SQL实战41-61

41. 构造一个触发器audit_log,在向employees_test表中插入一条数据的时候,触发插入相关的数据到audit中

CREATE TRIGGER audit_log AFTER INSERT ON employees_test
BEGIN
INSERT INTO audit VALUES(NEW.id,NEW.name);
END;

注意构造触发器的语句

42. 删除emp_no重复的记录,只保留最小的id对应的记录。

DELETE FROM titles_test
WHERE emp_no IN (SELECT emp_no FROM titles_test GROUP BY emp_no HAVING count(emp_no)>1)
AND id NOT IN (SELECT MIN(id) FROM titles_test GROUP BY emp_no)

删除记录用DELETE FROM 表名,后面跟筛选条件

43. 将所有to_date为9999-01-01的全部更新为NULL,且 from_date更新为2001-01-01。

UPDATE titles_test
SET to_date = NULL, from_date = '2001-01-01'
WHERE to_date = '9999-01-01'

更新记录用UPDATE 表名 SET……WHERE

44. 将id=5以及emp_no=10001的行数据替换成id=5以及emp_no=10005,其他数据保持不变,使用replace实现。

UPDATE titles_test 
SET emp_no = REPLACE(emp_no,10001,10005)
WHERE id =5

注意REPLACE 的用法

45. 将titles_test表名修改为titles_2017。

ALTER TABLE titles_test RENAME TO titles_2017

在MYSQL 中 还可以用 RENAME TALBE 旧表名 TO 新表名,SQLite中只能用ALTER......

46. 在audit表上创建外键约束,其emp_no对应employees_test表的主键id。

DROP TABLE audit;
CREATE TABLE audit(
    EMP_no INT NOT NULL,
    create_date datetime NOT NULL,
    FOREIGN KEY(EMP_no) REFERENCES employees_test(ID));

MYSQL 中可以用 ALTER TALBE 表名 ADD FOREIGN KEY......REFERENCE......

47. 存在如下的视图:create view emp_v as select * from employees where emp_no >10005; 如何获取emp_v和employees有相同的数据?

SELECT *
FROM employees
WHERE emp_no>10005
这题太bug了,视图存在的很没价值,视图就是虚拟表,当表用就好了


48.将所有获取奖金的员工当前的薪水增加10%。

UPDATE salaries
SET salary = salary*1.1
WHERE emp_no IN (SELECT emp_no FROM emp_bonus)

注意是更新数据,不是把查找结果加10%

49. 针对库中的所有表生成select count(*)对应的SQL语句

SELECT 'select count(*) from '||name||';'
FROM sqlite_master
WHERE type='table'

SQLite 的系统表是sqlite_master,表的类型是table

MYSQL 中用

select concat('select count(*) from ',t.TABLE_NAME) AS cnts  
from (select TABLE_NAME 
      from information_schema.TABLES
      where TABLE_SCHEMA = database()) t;

50. 将employees表中的所有员工的last_name和first_name通过(')连接起来。

SELECT  (last_name||"'"||first_name) AS name
FROM employees

51. 查找字符串'10,A,B' 中逗号','出现的次数cnt。

SELECT LENGTH('10,A,B')-LENGTH(REPLACE('10,A,B',',',''))

52. 获取Employees中的first_name,查询按照first_name最后两个字母,按照升序进行排列

SELECT first_name
FROM employees
ORDER BY SUBSTR(first_name,-2,2)

SQLite 中截取字符串长度的函数是 SUBSTR(被截取的字符串,开始位置,截取长度)

MYSQL中可以用MID( ),LEFT( ),RIGHT( )等

53. 按照dept_no进行汇总,属于同一个部门的emp_no按照逗号进行连接,结果给出dept_no以及连接出的结果employees

SELECT dept_no,GROUP_CONCAT(emp_no)
FROM dept_emp 
GROUP BY dept_no

注意GROUP_CONCAT的用法

54. 查找排除当前最大、最小salary之后的员工的平均工资avg_salary。

SELECT AVG(salary)
FROM salaries
WHERE salary not in (SELECT MAX(salary) FROM salaries )
AND salary not in (SELECT MIN(salary) FROM salaries )
AND to_date ='9999-01-01'

55. 分页查询employees表,每5行一页,返回第2页的数据

SELECT *
FROM employees
LIMIT 5,5

其实是手动分页。。。

56. 获取所有员工的emp_no、部门编号dept_no以及对应的bonus类型btype和recevied,没有分配具体的员工不显示

SELECT d.emp_no,d.dept_no,b.btype,b.recevied
FROM dept_emp d LEFT JOIN emp_bonus b ON d.emp_no = b.emp_no 

57. 使用含有关键字exists查找未分配具体部门的员工的所有信息。

SELECT e.*
FROM employees e
WHERE NOT EXISTS(SELECT d.* FROM dept_emp d WHERE e.emp_no = d.emp_no )

注意EXISTS的用法

58. 重复47题

59. 获取有奖金的员工相关信息。

SELECT e.emp_no,e.first_name,e.last_name,b.btype,s.salary,
(CASE WHEN b.btype =1 THEN s.salary*0.1
 WHEN b.btype =2 THEN s.salary*0.2
 ELSE  s.salary*0.3
 END) AS bonus
FROM employees e,emp_bonus b,salaries s
WHERE e.emp_no = b.emp_no AND e.emp_no = s.emp_no AND s.to_date = '9999-01-01'

60. 按照salary的累计和running_total,其中running_total为前两个员工的salary累计和,其他以此类推。

SELECT s1.emp_no,s1.salary,(SELECT SUM(s2.salary) 
                            FROM salaries s2 
                            WHERE s2.emp_no<=s1.emp_no AND s2.to_date = '9999-01-01') AS running_total
FROM salaries s1
WHERE s1.to_date = '9999-01-01'
ORDER BY s1.emp_no

61. 对于employees表中,按first_name升序排序后,给出奇数行的first_name

SELECT e2.first_name
FROM employees e2
WHERE (SELECT COUNT(*) FROM employees e1 WHERE e2.first_name<=e1.first_name)%2=1
注意用COUNT来表示序号




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值