mysql代码注释,练习用

来源:互联网 发布:淘宝cos店便宜 编辑:程序博客网 时间:2024/05/16 10:05
select * from emp;select empno ,ename from emp;select ename,sal*12 as "年薪" from emp;-- as 可以省略,select ename as "姓名",sal*12 as "年薪"  ,sal as"月薪" ,job from emp;select 5 from emp;/*distinct[不允许重复的]*/select deptno from emp;-- 14行记录select  distinct deptno from emp;select distinct comm from emp;--空也也是个唯一的数值,也可以过滤掉。只剩下唯一的一个。select distinct comm,deptno from emp;-- 这行是把他们这一组的组合进行过滤了。select comm, distinct deptno from emp;--这一组有错,是因为前面的com是14行,--然而后面的过滤了之后是三行。明显出现错误了。/*between的用法,在某个范围之间。*/--查找工资在1500和3000之间所有员工之间的信息select * from empwhere sal>=1500 and sal<=3000;select * from empwhere sal between 1500 and 3000;--和上面的相同查询到的记录都是7个。--查询相反的区间。select * from empwhere sal <1500 or sal >3000 order by sal desc; --这里面的or和and的区别,否的否是并且select * from empwhere sal not between 1500 and 3000order by sal asc;--h和上面的写法是一样的,但是这里面需要注意or和and的用法就KO了/*in的用法[属于若干个孤立的数值。]*/select * from empwhere sal in (1500,3000);--这样查询只有1500和3000的工资的记录被查找了出来了,--等价于下面的。select * from empwhere sal =1500 or sal =3000;--有in就有not inselect * from empwhere sal not in(1500,3000);--下面和上面的是等价的。select * from empwhere sal !=1500 and sal !=3000;select * from empwhere sal <>1500 and sal <>3000;--<>这个也是不等于。--下面是top的用法。select * from emp;select top(2) * from emp;--把前面查询到的两行进行输出select top(30) percent * from emp;--把30%输出,14行记录输出了5行,所以不够的话是往上面走的。select top(10) * from emp where sal between 1500and 3000order by sal descselect * from emp where comm !=null;select * from empwhere comm <>null;-- 总结NULL不能参与!= <>运算 select * from empwhere comm =null;-- 也不能参与=运算。select * from emp where comm is null;select * from empwhere comm is not null;--总结,null可以参与的运算有 is 还有is not--任何类型的数据都可以为NULL;create table t1 (name varchar(20) ,cnt int ,riqi datetime);insert into t1 values(null,null,null);select * from t1;--所有的数据类都可以为NULL--输出每个员工的姓名,年薪,(年薪包括奖金)select ename as "姓名", sal*12+comm as "年薪" from emp;--错误哦哦。-- null不能参与一个具体值进行运算,最终结果就是没有结果。-- 本程序证明了NULL不能参与任何算术运算,否则还是没有结果的NULL-- 百度了一下select ename as"姓名",sal *12+isnull(comm,0) as"年薪" from emp;-- 现在就是KO了,  isNull函数可以解决这些问题、--isNull 如果comm是NILL就返回0 否则就返回comm/*下面是order by[以某个字段进行排序]*/select * from emp order by sal;-- 这个默认是升序select * from emp order by sal desc;--这样子写是降序select * from emp order by deptno ,sal ;--这样子是先按deptno 排序,然后发现deptno相同的时候在按照sal排序。-- 模糊查询。select * from emp where ename like '%a%';--把含有A的字母的名字给查询出来select * from emp where ename like 'a%'-- 首字母是A的咱们就输出select * from emp where ename like '%a'-- 只要是末尾的字母是A的就打印select * from emp where ename like '_a%' -- 只要第二个字母是A就打印 select * from emp where ename like '_[a-f]%'--只要是第二个字符是A-F的人打印select * from emp where ename like '_[^a-f]%' -- 把上面的取反得到的-- 加入我这里插入了这么一句,那么该如何查询到%的姓名呢,百度了一下得到了下面的结果insert into emp values (0001,'c%d',NULL,0001,null,0,null,20);select * from emp where ename like '%\%%' escape '\'--看,这样就查询出来了答案了,关键是把\当成了特殊字符对待,后面的是一个普通字符。-- 通配符/*和regex正则表达式一模一样  学过正则这些就不用再看了-- attintion 唯一需要注意的就是把like后面的加上单引号,代表区分关键字,说到了单引号,那么双引号在我们这里的使用代表的是一个对象的名称或者是别名。% 任意0个或者多个字符_ 下划线,代表的是任意的单个字符[a-f] 代表的是a-f的任意的单个字符[a,z] 代表的是a或者z[^a-f]代表的是取反,不是a-z的任意字符*//*模糊查询完成。大概也就这么多东西了。2016年2月11日16:37:21*//*聚合函数单行函数,每一行返回一个数值。多行函数,多行返回一个数值.聚合函数是多行的函数。*/select lower(ename)  from emp; --大写换成lower写。单行函数,每一行都返回一个数值select max(sal) from emp; --max是多行函数,因为多行返回的是一个数值。/*聚合函数的分类max()min()avg()count()*/select count(*) from emp --返回emp表里面所有记录的个数select count(deptno) from emp;-- 有重复的but还是15这说明deptno重复的记录还是被当成有效的了select count(distinct deptno) from emp; --挂上distinct 这样重复的记录就被过滤了。select count(comm) from emp; -- null不参与count的计算。返回值是4个,然而不是14个--------------------------------------------------------select max(sal) as "最高工资" ,min(sal) as "最低工资" ,count(*) "员工人数" from emp; -- 正确select max(sal) ,lower(ename) from emp;--返回的行数不一样,肯定是ERROR-- -- 下面开始的是分组了。use scott;--输出每个部分的编号,和该部门的平均工资select * from emp;select  deptno,avg(sal) as "部门的平均工资"  from emp group by deptnoselect deptno, ename from emp group by deptno; -- 使用group by 了之后,使用select只能出现分组后的整体信息,不能出现--组内的详细信息select deptno, job,avg(sal) as "工作部门平均工资" from emp group by deptno, joborder by deptno,job;use scottselect deptno ,avg(sal) as "部门的平均工资",min(sal) as"当前部门的最低工资",max(sal) as "当前部门的最高工资",sum(sal) as"当前部门的工资总和",count(*) as "部门员工数量"from empgroup by deptnoorder by deptno desc;--大部分的聚合函数好像都能在里面进行使用select comm, count(*) from emp group by comm;--查询奖金分组,NULL是被当成了一组来处理。--having 【对分组之后的信息进行过滤】/*【聚合函数】多行记录返回一个数值就叫做聚合函数。通常用于统计分组的信息、单行函数,每一行都返回一个数值。聚合函数,也就是多行函数,指的就是多行返回一个数值。*/select max(sal ) from emp;-- 输出部门平均工资大于 2000部门的部门的平均工资select deptno ,avg(sal) "平均工资", count(*) "人数"from emp group by deptnohaving avg(sal)>1;select deptno ,avg(sal) "平均工资",count(*) "人数" from empgroup by deptnohaving ename like '%a%' --error 不能这样过滤...-- having过滤的是分组过后的整体信息,-- where 是对原始的记录进行的过滤select deptno ,avg(sal) "平均工资" from empwhere ename like '%a%' group by deptnohaving avg(sal) >1;-- 这一句是把含有A字母的都加起来过滤然后在统计平均avgselect deptno ,avg(sal ) "平均工资" ,count(*) "人数", max(sal) "部门最高的工资" from empwhere ename like '%a%'group by deptnohaving avg(sal) >1; select  deptno as "部门编号" ,avg(sal) as "平均工资" ,count(*) as "部门的人数"from empwhere sal > 100group by deptnohaving count(*) >5select * from emp--链接查询 join--定义,将两个表或者两个表以上的表按照一定条件链接起来,--从中检索出满足的数据-- 内连接select "E".ename "员工的姓名","D".dname "部门的名称"from emp "E"join dept "D"on "E".deptno = "D".deptno--笛卡尔乘积。 emp是15行 然而dept是5行,这里面查询到了75行。 5*15-- 列数是他们的相加之和-- 就是把emp表的所有记录和 dept的第一行记录来拼接到一起 ,然后在和下面的第二行记录再拼接到一起。-- 没有设置连接的条件,所以把所有的条件都连接到一起来了。use scottselect * from emp,dept where empno =7369 --这样过滤的结果是 5行每一个对应的都具有一个7369-- 还是 11 列,输出的是5行11列-- 别名是双引号,  如果是字符串呢,字符串是单引号,不要和编程语言来搞混了select "E".ename "员工姓名","D".dname "地址信息"from emp "E"join dept "D"on 1=1-- on不能省略 有join就有onselect deptno from emp "E"join dept "D"on 1=1 --错误,不能知道deptno是那一列select "D".deptno from emp "E"join dept "D"on 1=1 --正确,这里面知道了是D的deptno,把D换成E也是一样的效果select * from emp "E"join dept "D"on 1=1; --正确,有两列是deptno一个是emp的一个是dept的select   ename as "员工姓名",  "员工表".deptno as "员工表的部门编号" from emp "员工表"join dept "部门表"on "员工表".deptno ="部门表".deptnoorder by "员工表".deptno asc--------------------------------------------select * from emp ,deptwhere emp.deptno =dept.deptno -- 15条记录 11列select  * from empjoin depton emp.deptno =dept.deptno -- 15条记录 11列--这两个字实现的结果是一样子的--where可以使用对原始的数据进行过滤,--join on可以对产生的那个临时表进行再次过滤。------------------------------------------ 92版本select ename "员工姓名", "E".deptno "工作部门编号", loc "部门地址"from emp "E",dept "D"where "E".sal>2000  and "E".deptno ="D".deptnoselect ename "员工姓名",  "E".deptno "部门编号" ,loc "部门地址"from emp "E"join dept "D"on "E".deptno ="D".deptnowhere "E".sal > 2000--这个和上面的是一模一样--  把工资大于 2000 的员工的姓名和部门的名称输出,和工资等级select "E".ename ,"D".dname ,"S".gradefrom emp "E"join dept "D"on "E".deptno ="D".deptnojoin salgrade "S"on "E".sal >"S".losal and "E".sal <"s".hisalwhere "E".sal >2000select "E".ename ,"D".dname ,"S".gradefrom emp "E"join dept "D"on "E".deptno ="D".deptnojoin salgrade "S"on "E".sal >"S".losal and "E".sal <"S".hisalwhere "E".sal >2000 use scottselect "E".ename ,"D".dname ,"S".gradefrom emp "E",dept "D" ,salgrade "S"where "E".deptno ="D".deptno and("E".sal >"S".losal and "E".sal <"S".hisal)  and "E".sal>2000-- 上面的两个是等价的--内连接--下面输出的是5的倍数, 15行记录 因为我们的emp表里面有 3个deptno为10的记录use scottselect *  from emp  ,deptwhere emp.deptno =10-- 14行记录,因为我们的dept表里面的 只有一个10那一个和emp表里面的进行了数据的组合 1*14 =14select * from emp, deptwhere dept.deptno = 10delete from emp where empno=1select *from empjoin depton dept.deptno=10select * from emp join depton 1=1where dept.deptno = 10--输出工资最高的前三名的每个员工的姓名,工资,工资等级,部门名称select top 3 "E".ename , "E".sal, "S".grade ,"D".dnamefrom emp "E" join dept "D"on "E".deptno = "D".deptnojoin salgrade "S"on "E".sal between "S".losal and "S".hisal--where "E".ename not like '%K%'order by "S".grade desc--求出每个员工的姓名,部门编号,新水和等级select "E".ename ,"E".deptno,"E".sal,"S".gradefrom emp "E"join salgrade "S"on "E".sal between "S".losal and "S".hisalselect * from empselect * from salgrade-- 嵌套查询 求出上司的编号和姓名select *  from empwhere empno in(select mgr from emp)--求出平均新水最高的部门编号和部门的平均工资select deptno ,avg(sal)"部门的avg"from emp group by deptno--输出大于最低工资的人的前三个人的姓名 工资,部门编号部门名称工资等级输出select top 3 "T".ename ,"T".sal,"T".deptno,"D".dname ,"S".gradefrom(select * from emp"E"where sal>(select min(sal) from emp)) "T"join dept "D"on "T".deptno ="D".deptnojoin salgrade "S"on "T".sal between "S".losal and "S".hisalorder by sal ascselect * from emp,dept; --70行 11列select * from dept,emp --和上面的是一样的select  * from emp ,dept where 1=1select * from emp ,dept where empno=7369;--5行select * from emp,dept,where deptno =10;--报错了select  * from emp ,dept where dept.deptno =10; --14行记录select * from emp,dept where emp.deptno =10 -- 5的倍数select * from empjoin depton 2>1where dept.deptno=10; --和一条是等价的关系。select * from emp ,dept;select  * from empjoin depton 1=1-- 70行 11列。和上面的一条是等价的select * from empjoin depton dept.deptno=emp.deptno  and emp.sal>2000;--连接条件和 过滤的条件可以卸载一起等同于下面的写法select * from empjoin depton dept.deptno=emp.deptnowhere emp.sal>2000;--和上面的等价,但是我感觉下面的更标准化一些。--  把工资大于 1500的所有员工按照部门分组,把部门的平均工资大于2000的最高的前两--个部们的编号,部门的名称,部门的平均工资的等级select * from emp "E"join(select top 2 "E".deptno ,"D".dname,"S".gradefrom emp "E"join dept "D"on "E".deptno ="D".deptnojoin salgrade "S"on "E".sal between "S".losal and "S".hisalwhere "E".sal>1500group by "E".deptnohaving avg("E".sal)>2000order by ("E".sal) desc) "T"-- 外连接select * from emp "E"left join dept "D"on "E".deptno ="D".deptno-- 14行,每一个只有一个能够连接成功select * from dept "D"left join emp "E"on "E".deptno ="D".deptno-- 至少是5行,有多个连接成功的也可以多个都可以连接成功-- 整体16行记录:-- 前面的10-30都可以在EMP表当中找到,只剩下了40,50因为找不到,所以为NULL--完全链接--如果不写是inner -- 结果包含三部分/*两个表中的匹配所有的行记录。2 左表中那些在右表中找不到的记录,这些记录右边全部为NULL3右表中那些在左表中找不到的记录,这些左边记录全部为NULL-- 交叉连接select * from emp cross join dept 等价于select * from emo ,dept--自连接。自己链接自己,*/--就是说一张表自己把自己链接起来-- 例子--不允许使用聚合函数,求薪水最高的员工的信息select * from emp where sal =(select max(sal)  from emp)select * from empwhere empno not in(select distinct "E1".emp)--输出每个员工的姓名,工资,和上司的姓名select "E1".ename ,"E1".sal,"E2".enamefrom emp "E1"join emp "E2"on "E1".mgr ="E2".empno--有问题啊,没有那个5000的员工select "E1".ename ,"E1".sal,"E2".enamefrom emp "E1"join emp "E2"on "E1".mgr ="E2".empnounion select ename ,sal,'已经是最大的boss' from emp where mgr is null--联合,就是指的是表和表之间的关系以纵向的关系链接在一起-- 以前都是横向的链接在一起的--若干个select子句要是想联合成功的话,必须满足两个条件。-- 列数是相等的-- 输出列的数据类型至少是兼容的create table student2(student_id int primary key ,student_name nvarchar(200) not null)select  * from student2;insert into student2(student_id,student_name) values(1,'张三');insert into student2(student_id,student_name) values(2,'李四');insert into student2(student_id,student_name) values(2,'李四');-- 错误了insert into student2(student_name) values('张三');--错误drop table student2create table student2(student_id int primary key identity ,student_name nvarchar(20) not null,)select * from student2;insert into student2(student_name) values('张三'); insert into student2(student_name) values('张三');insert into student2 values ('李四'); --正确delete from student2 where student_name ='张三'-----------------------------------------------------------select * from empwhere sal=(select max(sal) from emp)--求出最大工资的员工的相关信息。select * from empwhere sal = (select max(sal)  from emp)--视图select deptno ,avg(sal) "avg_sal" from empgroup by deptno select * from (select deptno ,avg(sal ) "avg_sal"  from empgroup by deptno)"T"where "T"."avg_sal"=(select max("E"."avg_sal" ) from (select deptno ,avg(sal) "avg_sal"from emp group by deptno ) "E") create view v$_emp_1as select deptno ,avg(sal) "avg_sal"from empgroup by deptno;create view v$_emp_2asselect * from empselect * from v$_emp_1;--说明了什么,说明了视图就相当于一个执行成功的Select 类型的语句啊-- 相当于一个临时的表select * from v$_emp_1where avg_sal =(select max(avg_sal) from v$_emp_1)--避免冗余,避免了大量的sql语句--视图就是一个虚拟的表--格式/*create view 视图的名称as-- select 的前面不能写beginselect语句--select 的后面不能写end*/ 视图的优点简化查询,增加数据的保密性select * from emp;create view v$_emp3 asselect empno ,ename,job,mgr,hiredate ,comm,deptnofrom emp;--这里面就把sal工资给隐藏了。可以把v$_emp3给用户,然而emp不允许访问--这样做就保密了-- 我们可以通过视图来查询我们的数据,也可以根据更改虚拟的表--来更改我们所依附的表select * from emp;--视图的缺点,/*比如我们删除了原始的表,但是我们的视图我们没有删除,这样的话,我们一查询就ERROR了维护起来比较麻烦。只不过是简化查询,但是不能够加快系统的速度。只不过就是写代码的时候快乐一点而已注意点:First 创建视图的select 语句必须为计算列制定别名,Second视图不是物理表,然而是一张虚拟的表Thirdly 不建议通过视图来更新我们的物理表格 */--正确的写法 这里面我们没有利用Group By 他默认把所有的员工当成一组来处理了,--  他就是个这create view v$_aasselect avg(sal) "avg_sal" from emp;--错误,因为你没有对计算列制定别名,计算列!=原始的列create view v$_basselect avg(sal)  from emp;-- 现在都是查询的知识哦.-- 事务,主要用来保证数据的合理性,和并发处理的能力/*通俗点来说,事务可以保证数据不处于一种中间的不合理的状态,利用事务,可以保证多个用户共享数据的同时访问银行转钱,比如不能张三转了李四没有加上去,或者张三减少钱了李四没有收到的中间状态这样就是中间状态,这样的状态就是十分严重的问题。事务的机制和线程里面的锁是一样的。要么成功,要么失败,不能中间一般。*//*和Java买票的程序一模一样的,多个站点访问的是同样的200张火车票。多用户同时访问,叫做并发访问很复杂,就和张三和 李四 同时访问一个数据M的时候,A修改成了3B修改成了5谁最后是谁的所以,必须只能有一个用户来访问,其他的人在外面等待。线程的同步就是通过锁来弄的,synchronized直接使用事务的难度很大,很多人都是利用第三方的插件,一般人不需要管理细细的的细节。*/--begin transaction 开始事务-- commit transaction 提交事务-- 回滚(撤销)事务RollBack Transaction 我靠,还TM能回滚,你TM再逗我?-- 代码还能回滚?去求吧。告诉我怎么能回滚-- 哦哦 Suddenly I Know-- Java里面的try {-- ..........--  ...-- commit transaction -- }-- catch(Exception e)--{--回滚,或者把这个写到Finally 里面释放内存资源--}/*显示的事务,每个事务都是以begin transaction开启,以commit transaction 语句显示的结束。*//*事务的特性:原子性:事务是一个完整的操作,事务的各个步骤是不可以分割的,要么都执行,要么都不执行。一致性:当事务完成时,数据必须处于一致的状态,要么处于开始状态,要么处于结束状态,不允许处于中间状态。同样的请求过来,是隔离的隔离性:指的是当前的事务和其他未完成事务是隔离的,在不同的隔离级别下,事务的读取操作,可以得到的结果是不同的持久性:事务完成之后,它对数据库的修改将会永远的被保持,事务的log可以保证事务的的永久性。一旦提交之后,马上就持久了。废话,你都提交了,当然就是持久了。SqlServer 2005 甭管什么语句,写完就直接commit了、*/create database db_bankuse db_bank;create table bank(customerEname nvarchar(200),currentMoney money,)insert into bank("customerEname","currentMoney") values('张三',1000);insert into bank("customerEname","currentMoney") values('李四',2);alter table bank add constraint check_currentMoney check(currentMoney>=0.1);select * from bank;-- 现在把张三的钱打给李四。update bank set currentMoney = currentMoney -1000 where customerEname='张三';update bank set currentMoney =currentMoney +1000 where customerEname ='李四';--删除掉,我刚才执行的垃圾操作delete  from bank where customerEname ='张三';delete from bank where customerEname='李四'--自己百度搜索午饭式查询方法/*还需要学习索引,就是一个自然的目录,加快我们的查询,但是建立不合理,会慢。存储过程,游标,分情况去处理,00TL_SQL这个是第四点语言,命令,*/select str(1234.1234,6,2)/* *@auther 坤阿坤(kulak) *time 2016年1月24日20:13:48 *target Trigger触发器 * */  -- 商品表格 CREATE TABLE t_good(id INT PRIMARY KEY AUTO_INCREMENT, goodName VARCHAR(20),goodNum INT ) CREATE TABLE t_order(id INT PRIMARY KEY AUTO_INCREMENT,orderId INT,orderNum INT  )DELIMITER $  CREATE TRIGGER good_order_trigger AFTER INSERT ON t_order FOR EACH ROW BEGIN UPDATE t_good SET goodNum=goodNum-new.orderNum WHERE id=new.orderId; END $ -- 给里面的表做准备数据,哈哈 INSERT INTO t_good(goodName,goodNum)VALUES('Java编程思想',10), ('Java哈哈',10), ('Mysql',10) -- 测试表中的触发器good_order_trigger INSERT INTO t_order(orderId,orderNum)VALUES(1,3); -- 可以触发事件,发现第一本书的goodNum变成7了,这就对了。  -- 但是我发现还存在两种情况,当用户删除一个订单的时候,我们直接删除一个订单,我们是不是需要把对应的商品的数量再加上去呢? -- 注意,单独的一个表只能有一个触发器,就是insert只能有一个,delete有一个。现在我们解决上面的问题DELIMITER $  CREATE TRIGGER good_order_trigger2 AFTER DELETE ON t_order FOR EACH ROW BEGIN UPDATE t_good SET goodNum=(goodNum)+old.orderNum WHERE id =old.orderId; END $  -- 创建完成了,现在我们测试一下吧。old是删除的我们的数据  DELETE FROM t_order WHERE id=1;  -- 既然都这样了,我们不如把那个也操作了算了。还有一个是什么,update是吧,我根据自己的理解来个测试。 DELIMITER $CREATE TRIGGER good_order_trigger3AFTER TRIGGER t_orderFOR EACH ROWBEGINUPDATE t_good SET goodNum=goodNum+old.goodNum-new.goodNum WHERE id=old.orderId;END $ USE scott;SELECT * FROM emp;SELECT ename,sal*12+IFNULL(NULL,-0) AS "年薪" FROM emp;


原创粉丝点击