zoukankan      html  css  js  c++  java
  • (MySQL学习) 35.MySQL笔记(婷姐初级、周阳高级)

    复制代码
       1 #开启关闭服务
       2 #管理员启动cmd,,net start/stop mysql,,
       3 #登录数据库,,mysql 【-h localhost -P 端口号】 -u 用户名  -p,,
       4 #退出数据库,,exit,, / #ctrl+c
       5 #查看版本号,,mysql -V,,
       6 ##常见语句
       7 #查看当前所有数据库
       8 SHOW DATABASES;
       9 #打开指定的库,,use 库名;
      10 #查看某库所有的表,,show tables; // show tables from 库名;
      11  /*创建表,, create table(
      12     字段名称 字段类型,
      13     字段名称 字段类型
      14     );*/
      15 #查看表结构,,desc 表名;
      16 #修改字符集 set names gbk;
      17 #查看表内容,,select * from 表名;
      18 #插入内容,,insert into 表名 (id , name) values1,‘yangbo’);
      19 #更新修改内容,,update  表名 set name='yb' where id=1;
      20 #删除内容,,delete from 表名  where id=1;
      21 ##不区分大小写
      22 ##单行注释   #注释    -- 注释 
      23 ##多行注释  /* 注释 */
      24  ###data query language/ data manipulation lan/
      25 ### data define lan/transcation control lan/
      26 ###DQL数据查询语言
      27 ##进阶1 基础查询-----------------------------------------
      28 # select  (字段、常量、表达式、函数) from  表名;
      29 USE myemployees;
      30  SELECT
      31   job_id          #F12变规范
      32 FROM
      33   jobs;
      34   
      35 SELECT
      36   `manager_id`,  #`` 区分系统sql关键字和字段名
      37   `first_name`,
      38   #逗号自己加
      39    `email`
      40 FROM
      41   `employees`;
      42 
      43 SELECT * FROM employees;  
      44 
      45 SELECT    1+4;
      46 
      47 #查询函数
      48 SELECT VERSION();
      49 
      50 #起别名alias  便于理解 ,防止重名
      51 SELECT last_name AS 姓 , first_name ASFROM employees;
      52 SELECT last_name 姓 FROM employees ;  # 无AS
      53 SELECT last_name 'x  #i ng' FROM employees;
      54 
      55 #去重
      56 SELECT  DISTINCT department_id FROM employees;
      57 
      58 # + 号的作用
      59 SELECT 10+10;   #==20
      60 SELECT "10"+10; #==20
      61 SELECT '1o'+10; #==11
      62 SELECT 'oo'+10; #==10
      63 SELECT NULL+10; #==null
      64 
      65 #拼接文本,判断是否为null
      66 SELECT CONCAT(last_name,first_name)  AS 姓名 FROM employees;
      67 SELECT CONCAT(`first_name`,`job_id`,IFNULL(`commission_pct`,0)) AS infor 
      68 FROM employees;
      69 
      70 ##进阶2 条件查询--------------------------------------------
      71  /*
      72 select 查询列表  #3
      73 from 表名        #1
      74 where 条件       #2
      75 
      76 条件表达 <  >  =  !=  <>  <=  >=
      77 #逻辑表达  &&  ||  !   连接多条件表达
      78 #          and  or  not 
      79 #模糊查询  
      80     like   
      81     between  and
      82     in 
      83     is null  
      84 */
      85 USE `myemployees`;
      86 
      87 SELECT
      88   *
      89 FROM
      90   employees
      91 WHERE salary > 12000;
      92 
      93  
      94 
      95 SELECT
      96   last_name,
      97   `department_id`
      98 FROM
      99   `employees`
     100 WHERE `department_id` <> 90;
     101 
     102 
     103 SELECT 
     104     last_name,
     105     salary
     106 FROM 
     107     employees
     108 WHERE
     109     salary>=10000 AND salary<=20000;
     110 
     111 #查询部门编号不是在90-120,或者工资大于15000的员工信息
     112 SELECT *
     113 FROM  employees
     114 #where not(`department_id`>=90 and `department_id`<=120) or salary>15000;
     115 #where department_id not between 90 and 15000 or salary>15000;
     116 WHERE NOT(department_id BETWEEN 90 AND 15000) OR salary>15000;
     117 
     118 
     119 #模糊查询 通配符
     120 # % 表示任意多个字符  _ 表示1个字符 , %%不能代表null!!!!!!!!!!
     121 SELECT *
     122 FROM employees
     123 WHERE last_name LIKE '%a%';  #姓包含a
     124 SELECT *
     125 FROM employees
     126 WHERE last_name LIKE '_i%'; #查询第二个字符为i,注意%的使用
     127 SELECT *
     128 FROM `employees`
     129 WHERE last_name LIKE '_\_%'; #查询第二个字符为下划线。为转义符
     130 SELECT *
     131 FROM employees
     132 WHERE last_name LIKE '_$_%' ESCAPE '$'; #escape指定转义符为$
     133 
     134 #between A and B ===  >=A and <=B,所以 A<=B
     135 SELECT * 
     136 FROM employees
     137 WHERE `employee_id` BETWEEN 100 AND 120; 
     138 
     139 #in
     140 /*
     141 in === multiple or , 不支持通配符,因为or是=,不是like
     142 */
     143 SELECT * 
     144 FROM employees
     145 WHERE `job_id` IN ('AD_VP','IT_PROG');
     146 # where `job_id`='AD_VP' OR `job_id`='IT_PROG';
     147 
     148 
     149 #is null  /  is not null
     150 SELECT * 
     151 FROM  employees
     152 WHERE commission_pct IS NULL;
     153 
     154 SELECT ISNULL(`commission_pct`),commission_pct  #判断为null=1,notnull=0
     155 FROM `employees`;
     156 
     157 #安全等于 <=>
     158 SELECT * 
     159 FROM employees
     160 WHERE `job_id` <=> 'AD_VP';
     161 
     162 SELECT * 
     163 FROM employees
     164 WHERE salary <=> 12000;
     165 
     166 SELECT * 
     167 FROM employees
     168 WHERE commission_pct <=> NULL;
     169 
     170 
     171 ##进阶3 排序---------------------------------------------
     172 
     173 #ORDER BY 默认asc ,降序,放在查询最后(除limit之外)
     174 #工资从高到低
     175 SELECT * FROM `employees` ORDER BY salary DESC;
     176 
     177 #加筛选条件
     178 #按表达式排序
     179 #ifnull(字段,0),字段值为null,赋值为0,不为null,为原值
     180 SELECT salary, salary*12*(1+IFNULL(`commission_pct`,0)) AS 年薪
     181 FROM  employees
     182 ORDER BY salary*12*(1+IFNULL(`commission_pct`,0));
     183 
     184 #按照别名排序
     185 SELECT salary, salary*12*(1+IFNULL(`commission_pct`,0)) AS 年薪
     186 FROM  employees
     187 ORDER BY 年薪 DESC;  #说明order by 最后一步执行
     188 
     189 #按函数排序
     190 SELECT `last_name`,LENGTH(`last_name`)
     191 FROM `employees`
     192 ORDER BY LENGTH(`last_name`) DESC;
     193 
     194 #多条件排序 员工信息 先按工资升序,后按 员工编号降序
     195 SELECT *
     196 FROM employees
     197 ORDER BY salary ASC,`employee_id` DESC;
     198 
     199 
     200 ##进阶4 常见函数-------------------------------------------------
     201 
     202 /*
     203 函数分为单行和多行函数
     204 单行比如length(),肯定有返回值
     205     1.字符函数(处理字符串)
     206 多行函数,又称组函数,统计用
     207 */
     208 
     209 #一、 字符函数##########################
     210 
     211 #1.length,获取字符长度
     212 SELECT LENGTH('莫默123aaa');
     213 #UTF8中文为3个字节,GBK中文2个字节
     214 SHOW VARIABLES LIKE '%char%';
     215 
     216 #2.concat
     217 SELECT CONCAT(`last_name`,'_',`first_name`) AS 姓名 FROM employees;
     218 
     219 #3.upper lower 
     220 
     221 SELECT CONCAT(UPPER(last_name),LOWER(first_name)) 姓名 FROM employees;
     222 
     223 #4.substr / substring
     224 SELECT SUBSTR('李莫愁爱上了陆展元',7) AS output; #从第7个位置开始
     225 SELECT SUBSTR('李莫愁爱上了陆展元',1,3) AS output; #从第1个位置开始的三个字符
     226 
     227 #大写首字母
     228 SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),LOWER(SUBSTR(last_name,2)))
     229 FROM employees;
     230 
     231 #5 instr
     232 #返回substr在str中第一次出现的索引,若不匹配,返回0
     233 SELECT INSTR('杨不悔爱上了殷六侠','殷六侠') AS output;
     234 #substr和instr连用,取邮箱用户名
     235 SELECT SUBSTR(email,1,INSTR(email,'@')-1) FROM ..;
     236 #6. trim 
     237 #去掉首位空格或指定str
     238  SELECT TRIM('  莫默  ') AS output;
     239 SELECT TRIM('a' FROM 'aa默aa') AS output;
     240 
     241 #7. lpad
     242 #左填充str为10个字符长,用padstr填充
     243 SELECT LPAD('莫默',10,'*') AS output;
     244 
     245 #8. rpad
     246 SELECT RPAD('y',5,'-') AS output; 
     247 
     248 #9 replace
     249 # 在str中,from_str被to_str替代
     250 SELECT REPLACE('张无忌爱上了周芷若','周芷若','赵敏') AS output;
     251 
     252 #二、数学函数############################
     253 
     254 SELECT ROUND(1.4);
     255 SELECT ROUND(1.459,2);
     256 
     257 SELECT CEIL(1.01); # 取右  取≥该参数的最小整数
     258 
     259 SELECT FLOOR(-1.09); #往数轴 取左
     260 
     261 SELECT TRUNCATE(1.123456,4); #取小数点前4位
     262 
     263 #取余
     264 SELECT MOD(10,3);
     265 SELECT MOD(-10,3);  #结果和被除数正负一致
     266 SELECT 10%3; 
     267 
     268 #出一个随机数,范围0-1
     269 SELECT RAND(0123456);
     270 #三、日期函数##############################
     271 SELECT NOW();
     272 
     273 SELECT CURDATE();
     274 
     275 
     276 SELECT CURTIME();
     277 #获得指定的部分 year年 month月 date日 hour小时 minute分 second秒
     278 SELECT YEAR(NOW());
     279 SELECT YEAR('1994-09-10');
     280 SELECT YEAR(hiredate) FROM employees;
     281 SELECT MONTH(NOW());
     282 SELECT MONTHNAME(NOW()); #返回英文月
     283 
     284 #日期格式的字符  转换成指定的格式
     285 #%Y1994 %y94 %m01 %c1 %d30 %H24 %h12 %i00 59 %s00 59
     286 SELECT MONTHNAME( STR_TO_DATE('1994-4-2','%Y-%c-%d') )output ;
     287 #           日期型字符    该字符的格式
     288 /*
     289 #查询入职日期为1992-4-3的员工信息
     290 select * from employees where hiredate = '1992-4-3'; 
     291 若日期型字符格式为04-03 92
     292 select * from employees where hiredate = str_to_date('04-03 1992','%m-%d %Y');
     293 */
     294 #时间格式的转换为特定格式的字符串
     295 SELECT DATE_FORMAT(NOW(),'%Y年%m月%d日') 日期;
     296 #查询有奖金的员工的员工名和入职日期,要求该日期格式输出为xx月/xx日 xxxx年
     297  SELECT
     298   last_name 姓名,
     299   DATE_FORMAT (hiredate, '%m月/%d日 %Y年') 入职日期
     300 FROM
     301   employees
     302 WHERE commission_pct IS NOT NULL;
     303 
     304 #求日期之差
     305 SELECT DATEDIFF(CURDATE(),'1994-01-21');
     306 
     307 
     308 #四、 其他函数###################################
     309 SELECT VERSION();
     310 SELECT DATABASE();
     311 SELECT USER();
     312 SELECT PASSWORD('yb'); #加密
     313 SELECT MD5('yb');    #加密
     314 #五、流程控制函数###################################
     315 #if
     316 SELECT IF(10>5,1,0); #和excel的if一样
     317 SELECT IF(salary<20000,IF(salary<10000,'small','media'),'high') 
     318     grade #nesting 嵌套
     319 FROM employees;
     320 
     321 SELECT last_name, commission_pct,
     322  IF(commission_pct IS NULL,'呵呵','哈哈')   备注
     323 FROM employees;
     324 
     325 #case多条件判断,可以和select搭配,也可单独使用
     326 /*
     327 case 常量
     328 when 值1 then 显示的值1
     329 when 值2 then 显示的值2
     330 。。。
     331 else 要显示的值n
     332 end
     333 */
     334 #在部门30的,工资×1.1
     335 #在部门40的,工资×1.2
     336 #在部门50的,工资×1.3
     337 #其他部门,原工资
     338 SELECT `department_id`, salary, 
     339 CASE `department_id`
     340 WHEN 30 THEN salary*1.1
     341 WHEN 40 THEN salary*1.2
     342 WHEN 50 THEN salary*1.3
     343 ELSE salary
     344 END 
     345 AS 新工资
     346 FROM employees; 
     347 #excel嵌套大法
     348 SELECT department_id,salary,
     349 IF(department_id=30,salary*1.1,
     350 IF(department_id=40,salary*1.2,
     351 IF(department_id=50,salary*1.3,salary)))AS 新工资 
     352 FROM employees;
     353 
     354 /* 多重if
     355 case 
     356 when 条件1 then 显示的值1
     357 when 条件2 then 显示的值2
     358 。。。
     359 else 要显示的值n
     360 end
     361 */
     362 #工资<10000,small;10000<=工资<20000,media;20000<工资,high
     363 SELECT salary,
     364 CASE
     365 WHEN salary>20000 THEN 'high'
     366 WHEN salary>10000 THEN 'media'
     367 ELSE 'small'
     368 END
     369 AS grade 
     370 FROM employees;
     371 #excel嵌套大法
     372 SELECT salary,IF(salary<20000,IF(salary<10000,'small','media'),'high') 
     373                     grade #nesting 嵌套
     374 FROM employees;
     375 
     376 ##二、统计函数
     377 
     378 #sum avg max min count
     379 #sum avg只能处理数字型,maxmin、count可以字符型
     380 #全部忽略null值
     381 #可以搭配distinct,去重
     382 #和统计函数一同使用的时group by 后的字段。☆☆☆☆☆
     383 
     384 SELECT SUM(salary),AVG(salary),MAX(salary),MIN(salary),COUNT(salary)
     385 FROM employees;
     386 
     387 SELECT SUM(salary),ROUND(AVG(salary),2),MAX(salary),MIN(salary),COUNT(salary)
     388 FROM employees;
     389 
     390 SELECT SUM(`commission_pct`),MAX(hiredate)
     391 FROM employees;
     392 
     393 SELECT SUM(DISTINCT salary), COUNT(DISTINCT `commission_pct`),
     394     SUM(salary),COUNT(`commission_pct`)
     395 FROM `employees`;
     396 
     397 #count单独使用
     398 SELECT COUNT(*) FROM `employees`;#☆☆☆
     399 SELECT COUNT(1) FROM `employees`;
     400 
     401 #进阶5 分组查询 ------------------------------------------------
     402 /*
     403 select 统计函数,字段
     404 from 表名
     405 【where 包含表名字段的条件】  #不可使用别名
     406 group by 字段   #可使用别名
     407 【having 包含统计函数的字段】  #可使用别名
     408 【order by 字段】 #可使用别名
     409 
     410 */
     411 #简单分组查询:每个部门平均工资
     412 SELECT AVG(salary),`department_id`
     413 FROM employees
     414 GROUP BY `department_id`;
     415 #前筛选--分组查询:邮箱中包含a字符的,每个部门平均工资,
     416 #where要跟在from 后面一行
     417 SELECT AVG(salary),department_id,email
     418 FROM employees
     419 WHERE email LIKE '%a%'
     420 GROUP BY department_id;
     421 #有奖金的每个领导手下的员工最高工资
     422 SELECT MAX(salary),manager_id
     423 FROM employees
     424 WHERE commission_pct IS NOT NULL
     425 GROUP BY manager_id;
     426 #后筛选--分组查询:领导编号>102的每个领导手下员工的最低工资>5000的领导编号
     427 #,以及其最低工资
     428 SELECT MIN(salary),manager_id
     429 FROM employees
     430 WHERE manager_id>102           #优先考虑前筛选☆☆☆☆☆
     431 GROUP BY manager_id
     432 HAVING MIN(salary)>5000;
     433 #按函数--分组查询:按员工姓名长度分组,查询每组个数,筛选员工个数>5的有哪些
     434 SELECT COUNT(*),LENGTH(last_name)
     435 FROM employees
     436 GROUP BY LENGTH(last_name)
     437 HAVING COUNT(*)>5;
     438 #多字段--分组查询
     439 #每个部门每个工种的平均员工工资
     440 SELECT AVG(salary),department_id,job_id
     441 FROM employees
     442 GROUP BY department_id,job_id;
     443 #排序--分组查询
     444 #每个部门每个工种的员工平均工资,按照平均工资大小降序
     445 SELECT AVG(salary),department_id,job_id
     446 FROM employees
     447 GROUP BY department_id,job_id
     448 ORDER BY AVG(salary) DESC;
     449 
     450 #进阶6 多表连接查询-----------------------------------------------
     451 #当查询的字段来自多个表
     452 #分类:内连接:等值连接、非等值连接、自连接
     453 #      外连接:左外连接、右外连接、全外连接
     454 #      交叉连接
     455 
     456 ##92版 内连接    
     457 USE girls;
     458 SELECT NAME,boyName FROM beauty ,boys
     459 WHERE beauty.`boyfriend_id`=boys.`id`;
     460 
     461 #查询员工名和对应的部门名
     462 SELECT last_name,department_name
     463 FROM employees , departments
     464 WHERE employees.`department_id`=departments.`department_id`;
     465 #为表名起别名,且from先执行,所以select 里面的job.id有歧义,只能用别名去标明
     466 #查询员工名、工种号、工种名 #
     467 #SELECT last_name,employees.job_id,job_title
     468 SELECT last_name,e.job_id,job_title
     469 FROM employees e, jobs j
     470 WHERE e.`job_id`=j.`job_id`;
     471 
     472 
     473 #筛选--内连接
     474 #有奖金的员工名、部门名
     475 SELECT last_name,department_name
     476 FROM employees e,departments d
     477 WHERE e.`department_id`=d.`department_id`
     478 AND e.`commission_pct` IS NOT NULL;
     479 #查询城市名中第二个字符为o的部门名和城市名
     480 EXPLAIN SELECT department_name,city
     481 FROM departments d,locations l
     482 WHERE d.`location_id`=l.`location_id`
     483 AND l.`city` LIKE '_o%';
     484 
     485 #分组-内连接
     486 #查询每个城市的部门个数
     487 SELECT COUNT(*), city
     488 FROM departments d,locations l
     489 WHERE d.`location_id`=l.`location_id`
     490 GROUP BY l.`city`;
     491 #查询有奖金的每个部门的部门名和部门领导编号,以及该部门最低工资
     492 SELECT department_name,e.manager_id,MIN(salary)
     493 FROM departments d,employees e
     494 WHERE d.`department_id`=e.`department_id`
     495 AND e.`commission_pct` IS NOT NULL;
     496 
     497 #三表连接
     498 #查询员工名、部门名、所在城市
     499 SELECT last_name,department_name,city
     500 FROM employees e,departments d,locations l
     501 WHERE e.`department_id`=d.`department_id`
     502 AND d.`location_id`=l.`location_id`;
     503 
     504 #非等值连接
     505 #查询员工工资和工资级别
     506 SELECT salary, grade_level
     507 FROM employees e,job_grades g
     508 WHERE e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`;
     509 
     510 #自连接
     511 #查询员工名和上级名称
     512 SELECT a.last_name,b.last_name
     513 FROM employees a,employees b
     514 WHERE a.`manager_id`=b.`employee_id`;
     515 
     516 #99版内连接
     517 #查询员工名和对应的部门名
     518 SELECT last_name,department_name
     519 FROM employees e 
     520 JOIN departments d
     521 ON e.`department_id`=d.`department_id`;
     522 
     523 #为表名起别名,且from先执行,所以select 里面的job.id有歧义,只能用别名去标明
     524 #查询员工名、工种号、工种名 #
     525 SELECT last_name,e.job_id,job_title
     526 FROM employees e
     527 JOIN jobs j
     528 ON e.`job_id`=j.`job_id`;
     529 
     530 #筛选--内连接
     531 #有奖金的员工名、部门名
     532 SELECT last_name,department_name
     533 FROM employees e
     534 JOIN departments d
     535 ON e.`department_id`=d.`department_id`
     536 WHERE e.`commission_pct` IS NOT NULL;
     537 
     538 
     539 #查询城市名中第二个字符为o的部门名和城市名
     540 SELECT department_name,city
     541 FROM departments d
     542 JOIN locations l
     543 ON d.`location_id`=l.`location_id`
     544 WHERE l.`city` LIKE '%o%';
     545 
     546 #分组-内连接
     547 #查询每个城市的部门个数
     548 SELECT COUNT(*),city
     549 FROM departments d
     550 JOIN locations l
     551 ON d.`location_id`=l.`location_id`
     552 GROUP BY l.`city`;
     553 
     554 #查询有奖金的每个部门的部门名和部门领导编号,以及该部门最低工资
     555 SELECT department_name,d.manager_id,MIN(salary)
     556 FROM employees e
     557 JOIN departments d
     558 ON e.`department_id`=d.`department_id`
     559 GROUP BY d.`department_name`;
     560 
     561 
     562 
     563 #三表连接
     564 #查询员工名、部门名、所在城市
     565 SELECT last_name,department_name,city
     566 FROM departments d
     567 JOIN  employees e ON e.`department_id`=d.`department_id`
     568 JOIN locations l ON d.`location_id`=l.`location_id`;
     569 
     570 #非等值连接
     571 #查询员工工资和工资级别
     572 SELECT salary, grade_level
     573 FROM employees e
     574 JOIN job_grades j 
     575 ON e.`salary` BETWEEN j.`lowest_sal` AND j.`highest_sal`;
     576 
     577 #自连接
     578 #查询员工名和上级名称
     579 SELECT a.last_name,b.last_name
     580 FROM employees a
     581 JOIN employees b ON  a.`manager_id`=b.`employee_id`;
     582 
     583 SELECT department_name,COUNT(*) 员工个数
     584 FROM departments d INNER 
     585 JOIN employees e
     586 ON d.`department_id`=e.`department_id`
     587 GROUP BY d.`department_name`
     588 HAVING COUNT(*)>3
     589 ORDER BY  员工个数 DESC;
     590 
     591 #左外连接#查询非交集(内连接查询的即为交集)
     592 SELECT b.*, bo.boyName
     593 FROM beauty b       #主表
     594 LEFT JOIN boys bo
     595 ON b.`boyfriend_id`=bo.`id`
     596 WHERE bo.`boyName` IS  NULL;
     597 #右外连接
     598 SELECT bo.boyName,b.*
     599 FROM boys bo
     600 RIGHT JOIN beauty b
     601 ON bo.`id`=b.`boyfriend_id`
     602 WHERE bo.`boyName` IS  NULL;
     603 #-----
     604 SELECT bo.*,b.name
     605 FROM boys bo
     606 LEFT JOIN beauty b
     607 ON bo.`id`=b.`boyfriend_id`;
     608 
     609 #交叉连接(笛卡尔乘积)
     610 SELECT * FROM beauty;
     611 SELECT * FROM boys;
     612 SELECT b.*,bo.*
     613 FROM beauty b
     614 CROSS JOIN boys bo;
     615 SELECT b.*,bo.*
     616 FROM beauty b,boys bo;
     617 ####7种join大法
     618 #左拼
     619 SELECT * FROM a LEFT JOIN b ON a.id=b.id;
     620 #左拼左独有
     621 SELECT * FROM a LEFT JOIN b ON a.id=b.id WHERE b.id IS NULL;
     622 
     623 #右拼
     624 SELECT * FROM a RIGHT JOIN b ON a.id=b.id;
     625 #右拼右独有
     626 SELECT * FROM a RIGHT JOIN b ON a.id=b.id WHERE b.id IS NULL;
     627 
     628 #内连接
     629 SELECT * FROM a INNER JOIN b ON a.id=b.id ;
     630 
     631 ##全外连接(mysql不支持全外,使用union连接去重的特性,实现full join)
     632 SELECT * FROM a LEFT  JOIN b ON a.id=b.id
     633 UNION 
     634 SELECT * FROM a RIGHT JOIN b ON a.id=b.id;
     635 
     636 ##左独有  拼  右独有
     637 SELECT * FROM a LEFT JOIN b ON a.id=b.id WHERE b.id IS NULL;
     638 UNION
     639 SELECT * FROM a RIGHT JOIN b ON a.id=b.id WHERE b.id IS NULL;
     640 
     641 
     642 #习题 那个城市没有部门
     643 SELECT l.city ,d.department_name
     644 FROM locations l
     645 LEFT JOIN departments d
     646 ON l.`location_id`=d.`location_id`
     647 WHERE d.`department_name` IS NULL;
     648 
     649 #习题 查询部门名为SAL/IT的员工信息
     650 SELECT d.department_name,e.*
     651 FROM departments d
     652 LEFT JOIN employees e  #注意主表不同,结果不同(把lfet换成right,39行)
     653 ON e.`department_id`=d.`department_id`
     654 WHERE d.`department_name` IN( 'SAL' ,'IT');
     655 
     656 ##进阶7 子查询---------------------------------------
     657 #出现在其他语句的select查询语句为子查询
     658 #子查询出现的位置:    select后面
     659 #               仅支持标量子查询
     660 #            from后面
     661 #               仅支持表子查询(多行多列)
     662 #            where后面(**/having后面(** 663 #               标量子查询(一行一列)√
     664 #               列子查询(多行一列)  √
     665 #               行子查询(一行多列)
     666 #            exists后面
     667 #               表子查询
     668 /*
     669 #where和having后面:标量、列、行子查询
     670 特点: 子查询放在小括号内
     671     一般放在条件的右侧
     672     标量子查询一般搭配单行操作符使用:> < >= <= = <>
     673     列子查询一般搭配多行操作符使用 in any/some all
     674     查询过程中,子查询优先执行
     675 */
     676 ##标量子查询
     677 #案例1 谁的工资比Abel高?
     678 SELECT *
     679 FROM employees
     680 WHERE salary>( SELECT salary FROM employees WHERE last_name='Abel');
     681 #案例2 返回job_id和141号员工相同,salary比143号员工高的员工信息
     682 SELECT * 
     683 FROM employees
     684 WHERE job_id = 
     685     (SELECT job_id FROM employees WHERE employee_id=141)
     686 AND   salary>
     687     (SELECT salary FROM employees WHERE employee_id = 143);
     688 #案例3 返回工资最少的员工的信息
     689 SELECT * 
     690 FROM employees
     691 WHERE salary = (SELECT MIN(salary) FROM employees );
     692 #案例4 查询最低工资大于50号部门的最低工资的部门name和其最低工资(外加多表查询)
     693 SELECT MIN (salary), d.department_name
     694 FROM employees e
     695 JOIN departments d
     696 ON e.`department_id` = d.`department_id`
     697 GROUP BY d.department_name
     698 HAVING MIN (salary) >
     699   (SELECT
     700     MIN (salary)
     701   FROM
     702     employees
     703   WHERE department_id = 50);
     704 ##列子查询
     705 #案例1 返回location_id是1400或者1700的部门中所有员工姓名
     706 SELECT *
     707 FROM employees
     708 WHERE department_id IN (
     709  SELECT DISTINCT department_id 
     710  FROM departments
     711  WHERE location_id IN(1400,1700)
     712 );
     713 SELECT *
     714 FROM employees
     715 WHERE department_id =ANY (
     716  SELECT DISTINCT department_id 
     717  FROM departments
     718  WHERE location_id IN(1400,1700)
     719 );
     720 # is not in == <>all
     721 # is in == =any
     722 #返回其他工种中比job_id为'IT-PROG'工种任一工资低的员工号、姓名、jobid、salary
     723 SELECT employee_id,last_name,job_id,salary
     724 FROM employees
     725 WHERE salary < ANY(
     726     SELECT DISTINCT salary FROM employees WHERE job_id='IT_PROG'
     727 ) AND job_id <> 'IT_PROG';
     728 SELECT employee_id,last_name,job_id,salary
     729 FROM employees
     730 WHERE salary < (
     731     SELECT DISTINCT MAX(salary) FROM employees WHERE job_id='IT_PROG'
     732 ) AND job_id <> 'IT_PROG';
     733 #返回其他工种中比job_id为'IT-PROG'工种*所有*工资低的员工号、姓名、jobid、salary
     734 SELECT employee_id,last_name,job_id,salary
     735 FROM employees
     736 WHERE salary < ALL(
     737     SELECT DISTINCT salary FROM employees WHERE job_id='IT_PROG'
     738 ) AND job_id <> 'IT_PROG';
     739 SELECT employee_id,last_name,job_id,salary
     740 FROM employees
     741 WHERE salary < (
     742     SELECT DISTINCT MIN(salary) FROM employees WHERE job_id='IT_PROG'
     743 ) AND job_id <> 'IT_PROG';
     744 ##3、行子查询
     745 #查询员工编号最小,工资最高的员工信息
     746 
     747 SELECT * FROM employees
     748 WHERE employee_id = (SELECT MIN(employee_id) FROM employees)
     749 AND  salary = (SELECT MAX(salary) FROM employees);
     750 
     751 SELECT * FROM employees e
     752 WHERE (e.`employee_id` , e.`salary`) =(
     753     SELECT MIN(employee_id) ,MAX(salary) FROM employees);
     754 
     755 
     756 #二、select后面子查询,**仅支持标量子查询
     757 #每个部门的员工个数
     758 SELECT d.*,(
     759     SELECT COUNT(*)
     760     FROM employees e
     761     WHERE e.department_id = d.`department_id`) N
     762 FROM departments d;
     763 SELECT d.* ,COUNT(*) N
     764 FROM employees e,departments d
     765 WHERE e.`department_id`=d.`department_id`
     766 GROUP BY e.`department_id`;
     767 #员工号102的部门名
     768 SELECT (SELECT d.department_name
     769     FROM employees e,departments d
     770     WHERE e.department_id=d.department_id
     771     AND e.employee_id=102) N
     772 ;
     773 ##from 后面跟表子查询,表子查询必须要起别名
     774 #案例:每个部门的平均工资的工资等级
     775 SELECT a.avge,a.department_id, j.`grade_level`
     776 FROM (
     777     SELECT AVG(salary) avge,department_id
     778     FROM employees
     779     GROUP BY department_id
     780 ) a
     781 , job_grades j
     782 WHERE a.avge BETWEEN j.`lowest_sal` AND j.`highest_sal`;
     783 SELECT a.*, j.`grade_level`
     784 FROM (
     785     SELECT AVG(salary) avge,department_id
     786     FROM employees
     787     GROUP BY department_id
     788 ) a
     789 JOIN job_grades j
     790 ON a.avge BETWEEN j.`lowest_sal` AND j.`highest_sal`;
     791 
     792 ##exists (相关子查询)
     793 SELECT EXISTS(
     794     SELECT salary FROM employees WHERE salary = 23000
     795 );
     796 #返回布尔向量,0或1
     797 #有员工的部门名
     798 SELECT d.department_name
     799 FROM departments d
     800 WHERE d.department_id IN (SELECT e.department_id FROM employees e);
     801 
     802 SELECT d.department_name
     803 FROM departments d
     804 WHERE EXISTS 
     805 (SELECT * FROM employees e WHERE e.`department_id`=d.`department_id`);
     806 
     807 (SELECT
     808   e.*
     809 FROM
     810   employees e ,departments d
     811 WHERE e.`department_id` = d.`department_id`);
     812 #案例2 没有女朋友的男神信息
     813 USE girls;
     814 SELECT bo.*
     815 FROM boys bo
     816 WHERE NOT EXISTS (
     817     SELECT * FROM beauty b WHERE b.`boyfriend_id`=bo.`id`
     818 );
     819 ##习题:查询各部门中工资比本部门平均工资高的员工信息
     820 SELECT e.* 
     821 FROM employees e,(
     822     SELECT AVG(salary) av,department_id 
     823     FROM employees 
     824     GROUP BY department_id
     825 )a
     826 WHERE e.`department_id`=a.department_id
     827 AND e.`salary`>a.av;
     828 
     829 
     830 SELECT e.* ,e.`department_id` FROM employees e 
     831 JOIN (
     832     SELECT AVG(salary) av,department_id 
     833     FROM employees 
     834     GROUP BY department_id
     835 )a
     836 ON e.`department_id`=a.department_id
     837 WHERE e.`salary`>a.av;
     838 
     839 ##进阶8 分页查询--------------------------------------------
     840 #伪代码
     841 #    select 查询列表
     842 #    from 表名
     843 #    【join type
     844 #      where group by  having  order by 845 #    limit 【起始页=0】,size
     846 #公式:******limit (page-1)*size,size*********
     847 #*******************查询虚拟表的极值order by xx desc limit 1*******************
     848 #案例1 查询前5条员工信息
     849 SELECT * FROM employees LIMIT 0,5; #从0开始!!!!!!,substr是1开始
     850 SELECT * FROM employees LIMIT 5;
     851 #案例2 有奖金的员工信息,工资较高的前10名
     852 SELECT * 
     853 FROM employees
     854 WHERE commission_pct IS NOT NULL
     855 ORDER BY salary DESC
     856 LIMIT 0,10;
     857 #执行顺序
     858 /*
     859 select 查询列表        7
     860 from 表名        1
     861 连接类型 join 表2    2 #产生一个笛卡尔乘积
     862 on 连接条件        3 #根据连接条件筛选
     863 where 筛选条件        4
     864 group by 分组列表    5
     865 having 分组后筛选    6
     866 order by 排序列表    8
     867 limit 偏移,条目数    9
     868 */
     869 
     870 #子查询经典习题
     871 #案例1 查询平均工资最低的部门信息
     872 SELECT d.*
     873 FROM departments d
     874 JOIN (
     875     SELECT AVG(salary) ag ,e.department_id 
     876     FROM employees e
     877     GROUP BY e.`department_id`
     878     ORDER BY a.ag
     879     LIMIT 0,1
     880 ) a
     881 ON d.`department_id`=a.department_id
     882 ;
     883 #平均工资最高的job信息
     884 SELECT j.* 
     885 FROM jobs j,(
     886     SELECT AVG(salary) av,job_id
     887     FROM employees 
     888     GROUP BY job_id
     889     ORDER BY av DESC
     890     LIMIT 1
     891 ) a
     892 WHERE  j.`job_id`=a.job_id;
     893 
     894 #查询平均工资高于公司平均工资的部门
     895 SELECT a.department_id,a.av
     896 FROM (
     897     SELECT AVG(salary) av,department_id
     898     FROM employees
     899     GROUP BY department_id
     900 ) a 
     901 WHERE a.av>(
     902     SELECT AVG(salary) FROM employees
     903 );
     904 #查询公司中所有manager的详细信息
     905 SELECT b.*
     906 FROM employees a
     907 JOIN employees b
     908 ON  a.`manager_id`=b.`employee_id`
     909 GROUP BY b.`employee_id`;
     910 
     911 SELECT *
     912 FROM employees
     913 WHERE employee_id = ANY(
     914     SELECT DISTINCT manager_id
     915     FROM employees
     916     GROUP BY manager_id
     917 );
     918 #各部门中,最高工资最低的那个部门 的最低工资为
     919 SELECT MIN(salary)
     920 FROM employees 
     921 WHERE department_id =(
     922     SELECT department_id
     923     FROM employees a 
     924     GROUP BY department_id
     925     ORDER BY MAX(salary) 
     926     LIMIT 1)
     927 ;
     928 #查询平均工资最高的部门的manager信息
     929 #where 标量子查询结果为null时,如何判断
     930 SELECT *
     931 FROM employees e
     932 RIGHT JOIN (
     933     SELECT manager_id
     934     FROM employees
     935     GROUP BY department_id
     936     ORDER BY AVG(salary) DESC
     937     LIMIT 1
     938 ) a
     939 ON IFNULL(e.manager_id,1) = IFNULL(a.manager_id,1) ;
     940 
     941 SELECT
     942   *
     943 FROM
     944   employees e
     945 WHERE IFNULL (e.manager_id, 1) = IFNULL (
     946     (SELECT
     947       manager_id
     948     FROM
     949       employees
     950     GROUP BY department_id
     951     ORDER BY AVG (salary) DESC
     952     LIMIT 1),1
     953   );
     954 
     955 #查询生日在1988-1-1后的学生姓名和专业名称
     956 USE student;
     957 SELECT  s.`studentname`,m.`majorname`
     958 FROM student s
     959 JOIN major m
     960 ON s.`majorid`=m.`majorid`
     961 WHERE DATEDIFF(s.`borndate`,'1988-1-1')>0;
     962 #每个专业的男生女生人数
     963 SELECT m.`majorname`, sex,COUNT(*)
     964 FROM student s,major m
     965 WHERE s.`majorid`=m.`majorid`
     966 GROUP BY s.majorid , sex;
     967 #变横行
     968 SELECT majorid ,
     969 (SELECT COUNT(*) FROM student WHERE sex="男" AND majorid=s.`majorid`) 男,
     970 (SELECT COUNT(*) FROM student WHERE sex="女" AND majorid=s.`majorid`) 女
     971 FROM student s
     972 GROUP BY majorid;
     973 #查询专业和张翠山一样的学生的最低分
     974 SELECT MIN(score)
     975 FROM student s
     976 JOIN result r
     977 ON s.`studentno`=r.`studentno`
     978 WHERE majorid=(
     979     SELECT  majorid
     980     FROM student
     981     WHERE studentname = '张翠山'
     982 );
     983 #查询哪个专业没有学生,分别左连接,右连接
     984 SELECT m.*
     985 FROM major m
     986 LEFT JOIN (
     987     SELECT COUNT(*) AS a, majorid
     988     FROM student
     989     GROUP BY majorid
     990 ) n
     991 ON m.`majorid`=n.majorid
     992 WHERE n.a IS NULL;
     993 
     994 #没有成绩的学生人数
     995 SELECT COUNT(*)
     996 FROM result r
     997 RIGHT JOIN student s
     998 ON r.`studentno`=s.`studentno`
     999 WHERE r.`id` IS NULL;
    1000 
    1001 ##进阶9 联合查询-----------------------------------------------
    1002 /* 语法:查询语句1
    1003     union 【all】
    1004     查询语句2
    1005 特点:
    1006 查询结果来自多个表,且各表之间无关键列索引
    1007 1、查询列数一致
    1008 2、每个查询语句的列的排列一致
    1009 3、union会去重,显示全部为union all
    1010 */
    1011 SELECT c.id ,c.name FROM  china c
    1012 UNION ALL
    1013 SELECT s.id ,s.name FROM stuinfo s;
    1014 
    1015 ###DML语言 database manipulate language
    1016 #    插入insert
    1017 #    修改update
    1018 #    删除delete
    1019 
    1020 #插入语句
    1021 #方式一:insert into 表名(列名) values(值,'')
    1022 
    1023 USE girls;
    1024 INSERT INTO beauty(id,NAME,sex,borndate,phone,photo,boyfriend_id)
    1025 VALUES(13,'安妮·海瑟薇','','1980-1-1','188888888',NULL,NULL);
    1026 
    1027 #变量nullable,用null作为该字段值,或者不写该字段
    1028 INSERT INTO beauty(id,NAME,sex,borndate,phone)
    1029 VALUES(14,'三上悠亚','','1988-1-1','288888888');
    1030 
    1031 #列的顺序可以调换
    1032 #字段个数和字段值必须一一对应
    1033 #可以省略列名,默认为所有字段,且按照表中顺序排列
    1034 INSERT INTO beauty
    1035 VALUES(15,'妲露拉·莱莉','','1982-1-1','388888888',NULL,NULL);
    1036 
    1037 #方式二:insert into 表名 set 字段名=值...
    1038 INSERT INTO beauty 
    1039 SET id=16,NAME='刘涛',phone='12345678';
    1040 
    1041 #两种方式 PK
    1042 
    1043 #方式一可以插入多行
    1044 INSERT INTO beauty(id,NAME,sex,borndate,phone)
    1045 VALUES(17,'高圆圆','','1988-10-10','488888888'),
    1046 (18,'白百何','','1989-01-10','588888888');
    1047 
    1048 INSERT INTO beauty #效率高**********
    1049 SELECT 17,'高圆圆','','1988-10-10','488888888' UNION#*****
    1050 SELECT 18,'白百何','','1989-01-10','588888888';
    1051 
    1052 #方式一支持子查询#行子查询的结果为beauty的新值
    1053 INSERT INTO beauty(id,NAME,phone)
    1054 SELECT 19,'唐艺昕','688888888'; 
    1055 
    1056 #修改单表记录
    1057 #语法 update 表名 set 字段名=值.... where 筛选条件
    1058 UPDATE beauty 
    1059 SET NAME='唐嫣'
    1060 WHERE id=15;
    1061 
    1062 #修改多表记录
    1063 #修改张无忌的女朋友电话为18866669999
    1064 UPDATE beauty b JOIN boys bo
    1065 ON b.`boyfriend_id`=bo.`id`
    1066 SET phone = '18866669999'
    1067 WHERE bo.`boyName`='张无忌';
    1068 #没有男朋友的女神的男朋友都为id=2
    1069 UPDATE beauty b LEFT JOIN boys bo 
    1070 ON b.`boyfriend_id`=bo.`id`
    1071 SET b.`boyfriend_id`=2
    1072 WHERE bo.`id` IS NULL;
    1073 
    1074 #删除语句
    1075 #方式一
    1076 #单表删除 ,LIMIT 2 b表示删除两条记录
    1077 DELETE FROM beauty WHERE id=19 LIMIT 2;
    1078 
    1079 #多表删除
    1080 #删除黄晓明的信息以及他女朋友的信息
    1081 DELETE bo,b
    1082 FROM boys bo JOIN beauty b
    1083 ON b.`boyfriend_id`=bo.`id`
    1084 WHERE bo.`boyName`='黄晓明';
    1085 
    1086 #方式二
    1087 TRUNCATE TABLE boys;
    1088 
    1089 #两种方式PK 筛 率 断 返 滚
    1090 /*
    1091 1.delete可以加where,truncate不能
    1092 2.truncate效率高
    1093 3.对于自增列,delete删除后在插入,从断点处记录,
    1094   truncate删除后从1 开始记录
    1095 4.truncate无返回值,delete显示删除了多少行(多少行受影响)
    1096 5.truncate删除不能回滚,delete删除可以回滚
    1097 */
    1098 SELECT * FROM boys;
    1099 
    1100 DELETE FROM boys;
    1101 TRUNCATE TABLE boys;
    1102 INSERT INTO boys(boyName,userCP)
    1103 VALUES('张无忌',100),
    1104 ('鹿晗',800),
    1105 ('段誉',300);
    1106 
    1107 
    1108 ###DDL数据定义语言
    1109 #库的管理,表的管理
    1110 #库、表的创建create、修改alter,管理drop
    1111 #位置 programdata/mysql/data
    1112 
    1113 ##库的管理
    1114 #库的创建
    1115 CREATE DATABASE IF NOT EXISTS books;
    1116 #库的修改
    1117 RENAME DATABASE books TO  newbooks;#不稳定
    1118 #修改字符集
    1119 ALTER DATABASE books CHARACTER SET gbk;
    1120 #库的删除
    1121 DROP DATABASE IF EXISTS books;
    1122 
    1123 ##表的管理
    1124 #表的创建
    1125 #create table 表名(
    1126 #    列名 类型 【长度,约束】,
    1127 #    列名 类型 【长度,约束】
    1128 #    );
    1129 CREATE DATABASE IF NOT EXISTS books;
    1130 
    1131 CREATE TABLE  IF NOT EXISTS book (
    1132     id INT,
    1133     bookname VARCHAR(20), #(20)为必须
    1134     booauthorid INT,
    1135     publishtime DATETIME
    1136 );
    1137 CREATE TABLE author(
    1138     id INT,
    1139     b_name VARCHAR(20),
    1140     nation VARCHAR(20)
    1141 )
    1142 DESC author;
    1143 DESCRIBE author;
    1144 
    1145 #表的修改
    1146 DESCRIBE book;
    1147 #修改列名
    1148 ALTER TABLE book CHANGE COLUMN publishtime pubdate DATETIME;
    1149 #修改类型或约束
    1150 ALTER TABLE book MODIFY COLUMN pubdate TIMESTAMP;
    1151 #添加新列
    1152 ALTER TABLE book ADD COLUMN annual DOUBLE ;
    1153 ALTER TABLE stuinfo ADD COLUMN sex CHAR AFTER id;
    1154 ALTER TABLE stuinfo ADD COLUMN fam_id INT FIRST;
    1155 #删除列
    1156 ALTER TABLE book DROP COLUMN annual;
    1157 #修改表名
    1158 ALTER TABLE author RENAME bookauthor;
    1159 
    1160 ##表的删除
    1161 DROP TABLE IF EXISTS bookauthor;
    1162 SHOW TABLES;
    1163 
    1164 ##表的复制
    1165 CREATE TABLE author(
    1166     id INT,
    1167     b_name VARCHAR(20),
    1168     nation VARCHAR(20)
    1169 );
    1170 INSERT INTO author
    1171 VALUES
    1172     (1,'村上春树','日本'),
    1173     (2,'路遥','中国'),
    1174     (3,'王小波','中国');
    1175 
    1176 #仅复制表的结构,跨库:库名.表名
    1177 CREATE TABLE copy LIKE author;
    1178 #复制表的内容+结构
    1179 CREATE TABLE copy1 
    1180 SELECT * FROM author; 
    1181 #只复制部分数据
    1182 CREATE TABLE copy2
    1183 SELECT id ,nation
    1184 FROM author WHERE nation='中国';
    1185 #仅复制某些字段的结构
    1186 CREATE TABLE copy3 
    1187 SELECT id ,nation
    1188 FROM author
    1189 WHERE 0; #where 1=2;
    1190 
    1191 ###常见数值类型
    1192 /*
    1193 数值型:整数、小数(定点数、浮点数)
    1194 字符型:较短文本char、varchar,
    1195     较长文本text、blob(较长二进制)
    1196 日期型:
    1197 */
    1198 ##数值型:
    1199 /*整数:tinyint(3)、smallint(5)、mediumint(7)、int(10)、bigint
    1200     int有符号为正负最大10位,27********,无符号为最大正10位,49********
    1201 特点:  1。默认为有符号(-),unsgined关键字表示无符号
    1202     2。数字超过界值,警告,且用界值填充
    1203     3。有默认长度,长度表示显示的最大宽度,位数不够用0填补,但必须搭配zerofill
    1204     4。zerofill只能为无符号
    1205 */
    1206 USE test;
    1207 DROP TABLE  tab_int;
    1208 CREATE TABLE tab_int(
    1209     integer1 INT,
    1210     integer2 INT UNSIGNED,
    1211     integer3 INT(10) ZEROFILL
    1212 ); 
    1213 
    1214 INSERT INTO tab_int VALUES (-1234567890,1234567890,123);
    1215 INSERT INTO tab_int VALUES (-1234567890,12345678901,123);
    1216 DESC tab_int;
    1217 SELECT * FROM tab_int;
    1218 /*小数:
    1219 浮点型float(M,D)、double(M,D)
    1220 定点型dec(M,D)/decimal(M,D)
    1221 通用的情况下,优先float>double>decimal
    1222 特点: 1。M表示整数+小数位数
    1223     2.D表示小数位数
    1224     3.如果数值位数超过范围,则插入临界值
    1225     4.M D都可以省略,float和double随数据长度变化,但默认decimal(10,0)
    1226     5.decimal精度高,用于如货币运算
    1227 */
    1228 CREATE TABLE tab_dem(
    1229     d1 FLOAT(5,2),
    1230     d2 DOUBLE(5,3),
    1231     d3 DECIMAL
    1232 );
    1233 DROP TABLE tab_dem;
    1234 INSERT INTO tab_dem(d1) VALUES(123.12);
    1235 INSERT INTO tab_dem(d2) VALUES(123.1);
    1236 
    1237 SELECT * FROM tab_dem;
    1238 DESC tab_dem;
    1239 
    1240 ##文本类型
    1241 #较短文本 char varchar (二进制binary varbinary1242 #较长文本 text blob(二进制)
    1243 
    1244 #特点
    1245 /*
    1246     写法        M                特点        
    1247 char    char(M)        最大字符数,可以省略,默认1    固定长度    
    1248 varchar varchar(M)    最大字符数,不接省略        可变长度
    1249 
    1250             空间的耗费    效率
    1251             比较耗费    较高
    1252             比较节省    较低
    1253 
    1254 
    1255 */
    1256 #枚举 enum
    1257 CREATE TABLE tab_enum(
    1258     e1 ENUM('a','b','c')
    1259 );
    1260 DESC tab_enum;
    1261 INSERT INTO tab_enum VALUES
    1262     ('a'),    #不区分大小写
    1263     ('c');  #不在列举范围,则插入值为空
    1264 SELECT * FROM tab_enum;
    1265 
    1266 #集合 set 
    1267 CREATE TABLE tab_set(
    1268     s1 SET('a','b','c')
    1269 );
    1270 INSERT INTO tab_set VALUES
    1271     ('a'),   #不区分大小写
    1272     ('a,c'); #可加两个
    1273 SELECT * FROM tab_set;
    1274 
    1275 ##日期类型
    1276 /*分类:
    1277 date日期
    1278 time时间
    1279 year年
    1280         字节    范围        时区
    1281 datetime    8    1000-9999    不受时区影响
    1282 timestamp    4    1970-2038    受影响
    1283 
    1284 */
    1285 #datetime和timestamp(受时区,语法模式、版本影响,但更能反映当前时区的真实时间)
    1286 CREATE TABLE tab_date(
    1287     d1 DATETIME,
    1288     d2 TIMESTAMP
    1289 );
    1290 INSERT INTO tab_date 
    1291 VALUES    (NOW(),NOW());
    1292 SELECT * FROM tab_date;
    1293 #system时间为+8:00东八区
    1294 SHOW VARIABLES LIKE 'time_zone';
    1295 
    1296 SET time_zone = '+9:00';
    1297 SELECT DATE(NOW());
    1298 ##常见约束
    1299 /*
    1300 分类:六大约束
    1301     1,not null 保证该字段不为空
    1302         如ID、姓名
    1303     2,default默认 保证该字段有默认值
    1304 1305     3,primary key主键 用于保证该字段有唯一性,且非空
    1306         比如学号、编号
    1307     4,unique唯一键 用于保证该字段具有唯一性,可以为空
    1308         比如座位号
    1309     5,check【mysql不支持】 
    1310         比如0<年龄<99
    1311     6,foreign key外键 用于限制两表关联列在主表中该列的值
    1312         比如:employees.department_id in departments.department_id
    1313         
    1314 在创建表和修改表时,添加约束
    1315 
    1316 分类:    列级约束 :(除外键)六大常见约束都支持,但是check无效果、foreign key无效果
    1317     表级约束 :(三键)除了非空、默认都支持    
    1318     
    1319 主键和唯一键的PK
    1320         唯一性    是否允许为空    一个表有几个    是否允许组合
    1321     主键    √    ×        最多一个    √,但是不推荐
    1322       唯一键    √    √(只能有一个空)    可以有多个    √,但是不推荐
    1323       
    1324   组合的意思是,让ID和name的组合如:ID_name唯一且不为空    
    1325   
    1326   外键:1,要求在从表(stinf)设置外键
    1327     2,从表(stinf)的外键列要求和主表(major)的类型一致或兼容
    1328     3,主表(major)的关联列必须是一个key (一般为主键)
    1329     4,插入数据时,先插主表(major),后从表(stinf)
    1330     5,删除数据时,先删从表(stinf),后主表(major)***级联删除和级联置空
    1331 
    1332 */
    1333 
    1334 #列级约束
    1335 
    1336 CREATE DATABASE constrain;
    1337 CREATE TABLE stinf(
    1338     id INT PRIMARY KEY, #主键
    1339     stuname VARCHAR(20) NOT NULL UNIQUE,#非空 & 唯一键
    1340     gender CHAR(1) CHECK(gender='' OR  gender=''),#核查
    1341     seat INT UNIQUE,#唯一键
    1342     age INT DEFAULT 18,#默认
    1343     majorid INT REFERENCES major(id)#外键
    1344 );
    1345 
    1346 CREATE TABLE major(
    1347     id INT PRIMARY KEY,
    1348     mname VARCHAR(20) 
    1349 );
    1350 DESC stinf;
    1351 SHOW INDEX FROM stinf; #查看主键、外键、唯一键
    1352 
    1353 #表级约束
    1354 DROP TABLE IF EXISTS stinf;
    1355 CREATE TABLE IF NOT EXISTS stinf(
    1356     id INT,
    1357     stuname VARCHAR(20),
    1358     gender CHAR(1),
    1359     seat INT,
    1360     age INT,
    1361     majorid INT,
    1362     CONSTRAINT pk PRIMARY KEY(id),#主键
    1363     CONSTRAINT uq UNIQUE(seat),#唯一键
    1364     CONSTRAINT ck CHECK(gender IN ('','')),#核查
    1365     CONSTRAINT fk_stinf_major FOREIGN KEY(majorID) 
    1366                     REFERENCES major(id)#外键
    1367     #constriant用来给键起名字
    1368 );
    1369 SHOW INDEX FROM stinf; #查看主键、外键、唯一键
    1370 DROP TABLE IF EXISTS stinf;
    1371 
    1372 CREATE TABLE IF NOT EXISTS stinf(
    1373     id INT,
    1374     stuname VARCHAR(20),
    1375     gender CHAR(1),
    1376     seat INT,
    1377     age INT,
    1378     majorid INT,
    1379      PRIMARY KEY(id),#主键
    1380      UNIQUE(seat),#唯一键
    1381      CHECK(gender IN ('','')),#核查
    1382      FOREIGN KEY(majorID) REFERENCES major(id)#外键
    1383     
    1384 );
    1385 SHOW INDEX FROM stinf; #查看主键、外键、唯一键
    1386 #通用
    1387 DROP TABLE IF EXISTS stinf;
    1388 
    1389 CREATE TABLE IF NOT EXISTS stinf(
    1390     id INT PRIMARY KEY, #主键
    1391     stuname VARCHAR(20) NOT NULL,#非空
    1392     gender CHAR(1) CHECK(gender='' OR  gender=''),#核查
    1393     seat INT UNIQUE,#唯一键
    1394     age INT DEFAULT 18,#默认
    1395     majorid INT,
    1396     CONSTRAINT fk_stinf_major FOREIGN KEY(majorid) 
    1397                 REFERENCES major(id)#外键
    1398 );
    1399 SHOW INDEX FROM stinf; #查看主键、外键、唯一键
    1400 
    1401 ##修改约束
    1402 /*
    1403 
    1404 
    1405 */
    1406 DROP TABLE IF EXISTS stinf;
    1407 
    1408 CREATE TABLE IF NOT EXISTS stinf(
    1409     id INT,
    1410     stuname VARCHAR(20),
    1411     gender CHAR(1) NOT NULL,
    1412     seat INT,
    1413     age INT,
    1414     majorid INT
    1415 );
    1416 #列级约束修改
    1417 ALTER TABLE stinf MODIFY COLUMN id INT PRIMARY KEY ;
    1418 ALTER TABLE stinf MODIFY COLUMN age INT DEFAULT 18;
    1419 DESC stinf;
    1420 SHOW INDEX FROM stinf;
    1421 #表级约束修改
    1422 #主键也可以这样去添加,但是不能添加constraint 限制名    
    1423 ALTER TABLE stinf ADD CONSTRAINT u_seat UNIQUE(seat);
    1424 ALTER TABLE stinf
    1425   ADD CONSTRAINT fk_major_stinf FOREIGN KEY (majorid) REFERENCES major (id);
    1426 DESC stinf;
    1427 SHOW INDEX FROM stinf;
    1428 
    1429 ##修改表时删除约束
    1430 #1删非空约束
    1431 ALTER TABLE stinf MODIFY COLUMN gender CHAR(1);
    1432 #2删默认约束
    1433 ALTER TABLE stinf MODIFY COLUMN age INT;
    1434 #3删主键
    1435 ALTER TABLE stinf DROP PRIMARY KEY;
    1436 #4删唯一键
    1437 ALTER TABLE stinf DROP INDEX seat;
    1438 #5删除外键
    1439 ALTER TABLE stinf DROP FOREIGN KEY fk_major_stinf;
    1440 SHOW INDEX FROM FROM stinf;
    1441 
    1442 ##级联删除:关于从表有外键时,删除数据biubiu先删主表,级联可以先删从表
    1443 #级联删除
    1444 ALTER TABLE student ADD CONSTRAINT fk_stu_maj 
    1445     FOREIGN KEY(majorid) REFERENCES major(majorid) ON DELETE CASCADE;
    1446 DELETE FROM major WHERE majorid=3;
    1447 #级联置空
    1448 ALTER TABLE student DROP FOREIGN KEY fk_stu_maj;
    1449 ##无法设置成功!!??
    1450 ALTER TABLE student ADD CONSTRAINT fk_stu_maj 
    1451     FOREIGN KEY(majorid) REFERENCES major(majorid) ON DELETE SET NULL;
    1452 DELETE FROM major WHERE majorid=2;
    1453 
    1454 
    1455 
    1456 #标识列
    1457 /*
    1458 1 必须搭配  键(只限mysql)
    1459 2 至多一个标识列
    1460 3 标识列类型只能是数值
    1461 4 步长设置通过SET auto_increment_increment = 2;
    1462 5 标识列初始值可通过手动添加
    1463 
    1464 */
    1465 DROP TABLE tab_auto;
    1466 CREATE TABLE tab_auto(
    1467     id INT PRIMARY KEY AUTO_INCREMENT,
    1468     NAME VARCHAR(20) 
    1469 );
    1470 
    1471 INSERT INTO tab_auto(id,NAME) VALUES(NULL,'john');
    1472 INSERT INTO tab_auto(NAME) VALUES('john');
    1473 INSERT INTO tab_auto VALUES(NULL,'john');
    1474 INSERT INTO tab_auto VALUES(5,'lily'); #相当于设置了起始值
    1475 INSERT INTO tab_auto VALUES(NULL,'john');
    1476 
    1477 TRUNCATE TABLE tab_auto;
    1478 
    1479 SELECT * FROM tab_auto;
    1480 SHOW VARIABLES LIKE '%auto_increment%';
    1481 SET auto_increment_increment = 2; #设置步长
    1482 SET auto_increment_offset = 3; #mysql无作用
    1483 #修改表时 添加删标识列
    1484 DROP TABLE tab_auto;
    1485 CREATE TABLE tab_auto(
    1486     id INT,
    1487     NAME VARCHAR(20) 
    1488 );
    1489 ALTER TABLE tab_auto MODIFY id INT PRIMARY KEY AUTO_INCREMENT;
    1490 ALTER TABLE tab_auto MODIFY id INT;
    1491 
    1492 ##事务
    1493 /*分类:
    1494     隐式事务:insert update delete
    1495     显式事务:set autocommit=0;
    1496           strat transaction;
    1497           select insert update delete;
    1498           ***** 无create alter drop ******
    1499           commit;    /    rollback;
    1500 ACID
    1501 1 原子性atomicity:一个事务不可再分割,要么都执行要么都不执行
    1502 2 一致性consistency:一个事务执行会使数据从一个状态切换到另一个状态
    1503 3 隔离性isolation:一个事务的执行不受其他事务的影响
    1504 3 持久性durability:一个事务的提交会永久改变数据库的数据
    1505 
    1506 三种数据问题:
    1507     1脏读:T1 T2 ,T2更新没提交,T1读取,读取了临时无效的信息,若T2回滚
    1508     2不可重复度:T1读取,T2更新,T1再读取则信息变化
    1509     3幻读:T1读取,T2更新某些行,T1再读取,出现多行数据
    1510 
    1511 事务隔离级别:
    1512             脏读    不可重复读    幻读
    1513 read uncommitted    √    √        √
    1514 read committed        ×    √        √
    1515 repeatable read        ×    ×        √
    1516 serializable        ×    ×        ×
    1517 
    1518 mysql默认repeatable read
    1519 Oracle默认read committed
    1520 */
    1521 #查看当前隔离级别
    1522 SELECT @@tx_isolation;
    1523 #设置隔离级别
    1524 SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
    1525 SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
    1526 
    1527 SELECT @@tx_isolation;
    1528 #事务中delete 和truncate 的区别
    1529 
    1530 SET autocommit=0;
    1531 START TRANSACTION;
    1532 DELETE FROM stuinfo;
    1533 ROLLBACK;
    1534 SELECT * FROM stuinfo;
    1535 
    1536 SET autocommit=0;
    1537 START TRANSACTION;
    1538 TRUNCATE stuinfo;
    1539 ROLLBACK;
    1540 SELECT * FROM stuinfo;
    1541 COMMIT;
    1542 
    1543 #演示savepoint的使用
    1544 INSERT INTO stuinfo VALUES(1,1,'s','yb');
    1545 INSERT INTO stuinfo VALUES(2,2,'x','lz');
    1546 SELECT * FROM stuinfo;
    1547 COMMIT;
    1548 
    1549 SET autocommit=0;
    1550 START TRANSACTION;
    1551 DELETE FROM stuinfo WHERE id=1;
    1552 SAVEPOINT a;
    1553 DELETE FROM stuinfo WHERE id=2;
    1554 ROLLBACK TO a;
    1555 SELECT * FROM stuinfo;
    1556 COMMIT;
    1557 ##视图
    1558 /*
    1559 含义:虚拟表,和普通表一样
    1560 mysql5.1出现的新特性,是通过表动态生成的数据
    1561 
    1562 比如:一个班里面 分化出一个舞蹈班,有需要时,舞蹈班就可以直接出现
    1563 
    1564 视图和表的PK:
    1565 1 创建语法不通 view  table
    1566 2 视图只占sql语句的字节,表占空间
    1567 3 视图一般不能增删改
    1568 
    1569 
    1570 */
    1571 
    1572 #查询各部门平均工资级别
    1573 USE myemployees;
    1574 CREATE VIEW myv1
    1575 AS
    1576 SELECT AVG(salary) ag,department_id
    1577 FROM employees
    1578 GROUP BY department_id;
    1579 
    1580 SELECT v.ag ,j.`grade_level` FROM myv1 v
    1581 JOIN job_grades j
    1582 ON v.`ag` BETWEEN j.`lowest_sal` AND j.`highest_sal`;
    1583 
    1584 #查询平均工资最低的部门信息
    1585 SELECT d.department_name, m.department_id, m.ag 
    1586 FROM myv1 m JOIN departments d
    1587 ON d.`department_id`=m.`department_id`;
    1588 
    1589 #视图的修改
    1590 CREATE OR REPLACE VIEW myv1
    1591 AS
    1592 SELECT AVG(salary) AS average_salary,department_id
    1593 FROM employees
    1594 GROUP BY department_id;
    1595 
    1596 ALTER VIEW myv1 
    1597 AS 
    1598 SELECT AVG(salary) ag,department_id
    1599 FROM employees
    1600 GROUP BY department_id;
    1601 
    1602 #视图的删除
    1603 CREATE  VIEW myv2
    1604 AS
    1605 SELECT department_id
    1606 FROM employees
    1607 GROUP BY department_id;
    1608 
    1609 DROP VIEW myv1, myv2;
    1610 #视图的查看
    1611 DESC myv2;
    1612 SHOW CREATE VIEW myv2;
    1613 SHOW CREATE VIEW myv2G; #在 DOS中使用
    1614 
    1615 #通过视图增删改原始表
    1616 /*
    1617 在视图包含以下情况不能insert update delete包含以下sql语句:
    1618 1 分组函数、instinct、group by 、having 、union、union all
    1619 2 常量视图
    1620 3 select包含子查询
    1621 4 join
    1622 5 from一个不能更新的视图
    1623 6 where子句的子查询引用了from子句的表
    1624 
    1625 */
    1626 ##变量
    1627 /*
    1628 系统变量:全局变量、会话变量
    1629 自定义变量:用户变量、局部变量
    1630 */
    1631 
    1632 #一、系统变量、会话变量(一个查询编辑器一个会话)
    1633 /*
    1634 变量由系统提供,不是用户定义,属于服务器层面
    1635 
    1636 注意:如果是全局变量,则需要加global,如果是会话级别,则需要加session,默认session
    1637 
    1638 使用语法:
    1639 1,查看所有变量:
    1640 show global|session variables;
    1641 
    1642 2,查看满足条件的部分系统变量
    1643 show global|session variable like '%char%';
    1644 
    1645 3,查看某个指定变量的值
    1646 select @@global|session.变量名;
    1647 select @@global.flush;
    1648 
    1649 4,为某个变量赋值(跨连接有效,不能跨重启)
    1650 set @@global|session 变量名=值;
    1651 set   global|session 变量名=值;
    1652 
    1653 */
    1654 #自定义变量
    1655 /*
    1656 声明、赋值、使用(查看、比较、运算)
    1657 
    1658         作用域        定义和使用的位置         语法
    1659 用户变量    当前会话    会话的任何地方            必须加@,不限制类型
    1660 局部变量    begin end中    只能在begin end中的第一句话    不加@,限定类型
    1661 */
    1662 #1,用户变量 :  作用域:当前会话
    1663 
    1664 #1 声明并初始化
    1665 SET @用户变量名=值;
    1666 SET @用户变量名:=值;
    1667 SELECT  @用户变量名:=值;
    1668 
    1669 #2 赋值(更新用户变量的值)
    1670 #方式一
    1671 SET @用户变量名=值;
    1672 SET @用户变量名:=值;
    1673 SELECT  @用户变量名:=值;
    1674 
    1675 #方式二
    1676 SELECT 字段 INTO @用户变量名
    1677 FROM 表名;
    1678 
    1679 #使用
    1680 SELECT @用户变量名;
    1681 
    1682 #案例
    1683 SET @count:=1;
    1684 SELECT COUNT(*) INTO @count FROM employees;
    1685 SELECT @count;
    1686 
    1687 #2,局部变量
    1688 /*
    1689 作用域:只在定义它的begin 和 end 中有效
    1690 
    1691 */
    1692 
    1693 #声明 ---------必须放在begin后面第一句----------------------
    1694 DECLARE 变量名 类型;
    1695 DECLARE 变量名 类型 【DEFAULT 值】;
    1696 
    1697 #赋值
    1698     #方式一
    1699     SET 用户变量名=值;
    1700     SET 用户变量名:=值;
    1701     SELECT  @用户变量名:=值;
    1702 
    1703     #方式二
    1704     SELECT 字段 INTO 用户变量名 FROM 表名;
    1705     
    1706 #使用
    1707 SELECT 局部变量;
    1708 
    1709 ##存储过程和函数
    1710 /*
    1711 好处:提高代码的重用性、简化操作
    1712 */
    1713 
    1714 #存储过程
    1715 /*
    1716 定义:一组预先编译好的SQL语句集合
    1717 
    1718 
    1719 一、创建语法
    1720 create procedure 存储过程名(参数列表)
    1721 begin 
    1722     存储过程体(一组合法的SQL语句)
    1723 end
    1724 
    1725 注意:
    1726 1,参数列表包含三部分:
    1727 参数模式  参数名  参数类型 
    1728 in         id       int
    1729 
    1730 参数模式:
    1731 in :改参数可以作为输入,也就是该参数需要调用方 传入值
    1732 out  : 该参数可以作为输出,也就是该参数可以作为返回值
    1733 inout : 该参数既可以作为输出,又可以作为输入,即既需要传入值,也能返回值
    1734 
    1735 2,如果存储过程体只有一句话, begin 和 end 可以省略
    1736  存储过程体每条sql均需要结尾加;
    1737  存储过程的结尾可以使用 delimiter 重新设置
    1738  *********delimiter在新连接中要去dos重新设置*************
    1739  语法: delimiter 结束标记
    1740  案例: delimiter $
    1741  
    1742  二、调用语法
    1743  Call 存储过程名(实参列表);
    1744  */
    1745  ##空参列表
    1746  #案例:给girls.admin添加5条数据
    1747  
    1748 DELIMITER $
    1749 CREATE PROCEDURE myp1()
    1750 BEGIN 
    1751     INSERT INTO admin(username,PASSWORD)
    1752     VALUES('yb1',123),('yb2',123),('yb3',123),('yb4',123),('yb5',23);
    1753 END $
    1754 
    1755 CALL myp1()$
    1756 SELECT * FROM admin$
    1757 
    1758 ##in列表
    1759 #案例1:创建存储过程实现:根据女神名查询对应的男生信息
    1760 
    1761 CREATE PROCEDURE myp2(IN beautyname VARCHAR(20))
    1762 BEGIN
    1763     SELECT bo.*
    1764     FROM boys bo 
    1765     LEFT JOIN beauty b ON b.boyfriend_id=bo.id
    1766     WHERE b.name=beautyname ;
    1767 END $
    1768 
    1769 CALL myp2('热巴')$
    1770 
    1771 #出现 Incorrect string value: 'xC8xC8xB0xCD' for column,表示字符集不匹配
    1772 SET NAMES gbk$ #(sqlyog默认utf8, dos默认gbk)
    1773 
    1774 #案例2:创建存储过程实现,用户是否登录成功
    1775 
    1776 CREATE PROCEDURE myp3(IN username VARCHAR(20),IN PASSWORD VARCHAR(20))
    1777 BEGIN
    1778     DECLARE result INT DEFAULT 0; #声明
    1779     SELECT COUNT(*) INTO result   #赋值
    1780     FROM admin ad
    1781     WHERE ad.username=username AND ad.password = PASSWORD;
    1782     
    1783     SELECT IF(result=0,'失败','成功') "结果";  #使用
    1784 
    1785 END $
    1786 
    1787 ##out列表
    1788 #案例:创建存储过程实现:根据女神名返回对应的男生名
    1789 CREATE PROCEDURE myp4(IN beautyname VARCHAR(20),OUT boyname VARCHAR(20))
    1790 BEGIN
    1791     SELECT bo.boyname INTO boyname
    1792     FROM boys bo  JOIN beauty b
    1793     ON bo.id = b.boyfriend_id
    1794     WHERE b.name=beautyname;
    1795 END $
    1796 
    1797 CALL myp4('柳岩',@bname)$
    1798 SELECT @bname$
    1799 
    1800 #案例:创建存储过程实现:根据女神名返回对应的男生名和魅力值
    1801 CREATE PROCEDURE myp5(IN beautyname VARCHAR(20),OUT boyname VARCHAR(20),
    1802             OUT userCP VARCHAR(20))
    1803 BEGIN
    1804     SELECT bo.boyname ,bo.usercp INTO boyname ,usercp  #赋值
    1805     FROM boys bo  JOIN beauty b
    1806     ON bo.id = b.boyfriend_id
    1807     WHERE b.name=beautyname;
    1808 END $
    1809 /*
    1810 set @name='a'$
    1811 set @charm='b'$                           省略了声明
    1812 */
    1813 CALL myp5('柳岩',@name,@charm)$                   #相当于省去了声明
    1814 SELECT @name,@charm$                       #调用
    1815 
    1816 ##inout列表
    1817 #案例:返回a,b值的二倍
    1818 CREATE PROCEDURE myp6(INOUT a INT,INOUT b INT)
    1819 BEGIN
    1820     SET a=a*2;  #赋值
    1821     SET b=b*2;
    1822 END $
    1823 SET @aa=1$          #声明
    1824 SET @bb=2$
    1825 CALL myp6(@aa,@bb)$
    1826 SELECT @aa,@bb$     #调用
    1827 
    1828 ##课后案例
    1829 #存储过程实现传入用户名密码,插入admin
    1830 CREATE PROCEDURE p_insert(IN username VARCHAR(20), IN PASSWORD VARCHAR(20))
    1831 BEGIN
    1832     INSERT INTO admin(username,PASSWORD) VALUES(username,PASSWORD);
    1833 END $
    1834 CALL p_insert('yb','122103')$
    1835 SELECT * FROM admin$
    1836 #传入女神标号,返回姓名电话
    1837 CREATE PROCEDURE p_inf(IN id INT,OUT NAME VARCHAR(50), OUT phone VARCHAR(11))
    1838 BEGIN
    1839     SELECT b.name,b.phone INTO NAME,phone  #注意要赋值
    1840     FROM beauty b
    1841     WHERE b.id=id;
    1842 END $
    1843 CALL p_inf(2,@bname,@bphone)$   #省去声明
    1844 SELECT @bname ,@bphone$        #调用
    1845 
    1846 #传入两个女生生日日期,然后返回大小
    1847 CREATE PROCEDURE myp7(IN date1 DATE,IN date2 DATE,OUT result INT)
    1848 BEGIN 
    1849     SELECT DATEDIFF(date1,date2) INTO result;
    1850 END $
    1851 CALL myp7('1994-09-10',DATE(NOW()),@result)$
    1852 SELECT @result$
    1853 
    1854 #传入一个日期类型的日期,输出为******日格式
    1855 CREATE PROCEDURE myp8(IN nor_date DATETIME,OUT for_date VARCHAR(20))
    1856 BEGIN
    1857     SELECT DATE_FORMAT(nor_date,'%Y年%m月%d日') INTO for_date;
    1858 END $
    1859 CALL myp8(DATE(NOW()),@fd)$
    1860 SELECT @fd$
    1861 
    1862 #输入 小昭,返回 小昭 and 张无忌
    1863 CREATE PROCEDURE myp9(IN beautyname VARCHAR(20),OUT information VARCHAR(50))
    1864 BEGIN 
    1865     SELECT CONCAT(beautyname,'and',IFNULL(bo.boyname,'null'))  INTO information
    1866     FROM boys bo ,beauty b
    1867     WHERE b.boyfriend_id=bo.id
    1868     AND b.name=beautyname;
    1869 END $
    1870 CALL myp9('柳岩',@inf)$
    1871 SELECT @inf$
    1872 
    1873 #传入条目数和起始索引,查询beauty表记录,
    1874 CREATE PROCEDURE myp10(IN offsett INT,IN increment INT)
    1875 BEGIN 
    1876     SELECT * FROM beauty
    1877     LIMIT offsett,increment;
    1878 END$
    1879 
    1880 CALL myp10(3,5)$#从第3条记录开始,显示5条
    1881 
    1882 
    1883 #删除储存过程
    1884 DROP PROCEDURE myp7; #只能一个一个的删
    1885 #查看储存过程
    1886 SHOW CREATE PROCEDURE myp6G;#在dos执行 
    1887 
    1888 
    1889 ##函数
    1890 /*
    1891 定义:一组预先编译好的SQL语句集合
    1892 
    1893 区别:存储过程:可以有0个返回,也可以有多个返回,适合做批量插入、更新
    1894       函数:有且仅有1个返回值,适合做处理数据后返回一个结果
    1895 */
    1896 /*
    1897 一、创建语法:
    1898 create function 函数名(参数列表) returns 返回类型
    1899 begin
    1900     函数体;
    1901     return ;
    1902 end $
    1903 
    1904 注意:1参数列表 包含  (无参数模式) 参数名  参数类型
    1905       2函数体肯定有return语句,如果没有会报错
    1906       3函数体中仅有一句话,则可以省略begin和end
    1907       4使用delimiter语句设置结束标记
    1908 
    1909 二、调用语法
    1910 
    1911 select 函数名(参数列表)
    1912 */
    1913 
    1914 #--------------------------函数案例演示------------------------
    1915 #1 无参有返回  案例 :返回公司的员工个数
    1916 USE myemployees;
    1917 CREATE FUNCTION myf1() RETURNS INT
    1918 BEGIN
    1919     DECLARE c INT ; #声明
    1920     SELECT COUNT(*) INTO c #赋值
    1921     FROM employees;
    1922     RETURN c; #调用
    1923 END $
    1924 SELECT myf1()$
    1925 
    1926 #2有参有返回   
    1927 #案例:根据员工名返回工资
    1928 CREATE FUNCTION myf2( ename VARCHAR(20)) RETURNS INT
    1929 BEGIN 
    1930     DECLARE s INT;
    1931     SELECT salary INTO s
    1932     FROM employees e
    1933     WHERE e.last_name=ename;
    1934     RETURN s;
    1935 END $
    1936 SELECT myf2('chen')$
    1937 
    1938 #根据部门名返回该部门平均工资
    1939 CREATE FUNCTION myf3( dname VARCHAR(20)) RETURNS INT
    1940 BEGIN 
    1941     SET @s=0;
    1942     SELECT AVG(e.salary) INTO @s
    1943     FROM employees e JOIN departments d
    1944     ON e.department_id = d.department_id
    1945     WHERE d.department_name = dname;
    1946     RETURN @s; 
    1947 END $
    1948 SELECT myf3('IT')$
    1949 
    1950 #案例 :传入两个float ,返回二者之和
    1951 CREATE FUNCTION mysum(a FLOAT ,b FLOAT) RETURNS FLOAT
    1952 BEGIN
    1953     DECLARE absum FLOAT;
    1954     SELECT a+b INTO absum;
    1955     RETURN absum;
    1956 END $
    1957 #查看、删除函数
    1958 SHOW CREATE FUNCTION myf3G; #dos
    1959 DROP FUNCTION myf3;
    1960 
    1961 ##流程控制 ——----------------------------------------------
    1962 /*
    1963 顺序、分支、循环
    1964 */
    1965 #一、 分支
    1966 #if(条件,ture,false)
    1967 #case
    1968 /*
    1969 1、等值判断
    1970     
    1971     case 字段  
    1972     when 值1  then 返回值1
    1973     when 值2  then 返回值2
    1974     ...
    1975     else 返回值3
    1976     end 
    1977 
    1978 2、 条件判断
    1979     case
    1980     when 条件1  then  返回值1
    1981     when 条件2  then  返回值2
    1982     ...
    1983     else 返回值3
    1984     end
    1985 -----可以和select 、update 搭配,case返回的是 返回值1、返回值2...,位置不限------------
    1986 
    1987 
    1988 3、case可以单独使用,只能放在begin end中
    1989     case 字段  
    1990     when 判断条件1  then 语句1;
    1991     when 判断条件2  then 语句2;
    1992     ...
    1993     else 语句3;
    1994     end case;
    1995 */
    1996 
    1997 #案例
    1998 CREATE PROCEDURE grade_level(IN grade INT)
    1999 BEGIN
    2000     CASE 
    2001     WHEN  90< grade AND grade <= 100 THEN SELECT 'A' ;
    2002     WHEN  80< grade AND grade <=90   THEN SELECT 'B' ;
    2003     WHEN  70< grade AND grade <=80   THEN SELECT 'C' ;
    2004     ELSE  SELECT 'D' ;
    2005     END CASE;
    2006 END $
    2007 CALL grade_level(98)$
    2008 
    2009 #if 多重分支,只能用在begin end中
    2010 /*
    2011    if      条件1  then 语句1;
    2012    elseif  条件2  then 语句2;
    2013    ...
    2014    ELSE 语句n;
    2015    end if;
    2016 */
    2017 #传入成绩,显示等级
    2018 CREATE FUNCTION grade_level( grade INT) RETURNS CHAR
    2019 BEGIN 
    2020     IF grade>90 AND grade <= 100 THEN RETURN 'A';
    2021     ELSEIF grade >80 THEN RETURN 'B';
    2022     ELSE RETURN 'c';
    2023     END IF;
    2024 END$
    2025 
    2026 ##循环结构
    2027 /*
    2028 分类:while 、 loop 、 repeat
    2029 
    2030 循环控制 :
    2031 
    2032 iterate ,结束本次循环,继续进行下一次
    2033 leave  ,跳出,结束当前循环
    2034 出现循环控制时,必须给循环结构添加名称
    2035 */
    2036 
    2037 #1while
    2038 /*
    2039 【标签】while 循环条件 do 
    2040     循环体
    2041 end while 【标签】;
    2042 */
    2043 
    2044 #2,loop
    2045 /*
    2046 【标签】loop 
    2047     循环体
    2048 end loop 【标签】;
    2049 
    2050 可以模拟简单的死循环
    2051 
    2052 */
    2053 
    2054 #3,repeat 
    2055 /*
    2056 【标签】repreat 
    2057     循环体
    2058 until 结束循环体的条件
    2059 end repeat 【标签】;
    2060 */
    2061 
    2062 /*
    2063 loop一般实现简单死循环
    2064 while先判断后执行
    2065 repeat先执行后判断,无条件至少执行一次
    2066 */
    2067 #案例,根据次数插入到admin表中多条记录
    2068 CREATE PROCEDURE p_while1(IN insertcount INT)
    2069 BEGIN 
    2070     DECLARE i INT DEFAULT 1;
    2071     WHILE i<insertcount DO 
    2072         INSERT INTO admin(`username`,`password`) 
    2073             VALUES(CONCAT('rose',i),'123');
    2074         SET i=i+1;
    2075     END WHILE ;
    2076 END$
    2077 CALL p_while1(50)$
    2078 
    2079 #案例,根据次数插入到admin表中多条记录,到20次就停止
    2080 CREATE PROCEDURE p_while2(IN insertcount INT)
    2081 BEGIN
    2082     SET @i=1;
    2083     a:WHILE @i<insertcount DO 
    2084         INSERT INTO admin(`username`,`password`)
    2085             VALUES(CONCAT('xiaohu',@i),'0000');
    2086         IF @i>=20  THEN LEAVE a;
    2087         END IF ;
    2088         SET @i=@i+1;
    2089     END WHILE a;
    2090 END$
    2091 #案例,根据次数插入到admin表中多条记录,结尾为偶数
    2092 
    2093 CREATE PROCEDURE p_while3(IN insertcount INT)
    2094 BEGIN
    2095     SET @i=0;
    2096     a:WHILE @i<insertcount DO 
    2097         INSERT INTO admin(`username`,`password`)
    2098             VALUES(CONCAT('xiaohu',@i),'0000');
    2099         SET @i=@i+2;
    2100     END WHILE a;
    2101 END$
    2102 
    2103 CREATE PROCEDURE p_while4(IN insertcount INT)
    2104 BEGIN 
    2105     SET @i=1;
    2106     a :WHILE @i<insertcount DO 
    2107         SET @i=@i+1;
    2108         IF MOD(@i,2) !=0 THEN  ITERATE a;
    2109         END IF;
    2110         INSERT INTO admin(`username`,`password`) 
    2111             VALUES(CONCAT('ts',@i),'6666');
    2112     END WHILE a ;
    2113 END $
    2114 
    2115 ####高级sql
    2116 /*GA generally available;
    2117 
    2118 ##字符集
    2119 delimiter ;
    2120 show variables like '%char%';
    2121 
    2122 #插件式的存储引擎,将查询处理和其他的系统任务以及数据的存储提取相分离
    2123 
    2124 mysql 分四层
    2125     1连接层:与其他语言的链接,如Perl、Python
    2126     2服务层:mysql查询,内部优化
    2127     3引擎层:可拔插的引擎,innoDB、myISAM
    2128     4存储层:硬件
    2129 
    2130 #查看引擎
    2131 show engines;
    2132 show variables like '%engine%';
    2133 
    2134 #sql性能下降的原因
    2135     1查询语句写的烂
    2136     2索引失效(单值、复合)
    2137     3关联查询join太多
    2138     4服务器调优及各个参数设置(缓冲、线程数)
    2139 
    2140 
    2141 */    
    2142 ##索引 :是帮助提高mysql高效获取数据的【【 数据结构】】  
    2143  /*
    2144 *********排好序的快速查找数据结构*************
    2145 
    2146 数据本身之外,数据库还维护着一个满足特定查找算法的【数据结构】
    2147 这些数据结构以某种方式指向数据,这样就可以在这些数据的基础上实现
    2148 高级查找算法,这种数据结构就是索引。
    2149 
    2150 索引往往以索引文件的形式存储在磁盘上
    2151 
    2152 索引往往指的是B数(多路搜索树)结构组织的索引
    2153 
    2154 聚集索引、全文索引、复合索引、前缀索引、唯一索引默认都是使用B+树索引,统称索引。
    2155 
    2156 出了B+树类型,还有哈希索引(hash index)
    2157 
    2158 索引的优劣
    2159 优势:    提高数据检索的效率,降低数据库IO的成本(input and output)
    2160     降低数据排序成本,降低了CPU的消耗
    2161 劣势:    提高查询速度的同时,降低了更新表的速度(增删改时,索引也会发生变化)
    2162     数据量较大,需要花时间研究建立最优秀的索引
    2163     
    2164 索引分类:
    2165 单值索引:一个索引只包含单个列,一个表可以有多个单列索引(银行查卡号,ID卡等)
    2166       一个表最好不超5个单列索引
    2167 唯一索引:索引列的值必须唯一,但允许有空值
    2168 复合索引:一个索引包含多个列
    2169 全文索引:
    2170 
    2171 
    2172 ##索引的结构:类似于二叉树一样
    2173 树的宽度又数据量决定,查询的速度由树的高度决定。
    2174 判断次数(IO次数)==树的高度
    2175 
    2176 ##什么情况适合建索引
    2177 1主键自动建立唯一索引
    2178 2频繁作为查询条件的字段
    2179 3与其他表关联字段,如外键 应该建立索引
    2180 4频繁更新的字段不适合建索引
    2181 5where中用不到的字段不建索引
    2182 6尽量组合索引
    2183 7查询中排序的字段(若排序的字段多个,复合索引按照排序中的多个字段顺序建立)
    2184 8统计或分组字段(group by和索引有关)
    2185 ##什么情况不适合建索引
    2186 1表字段太少(3百万以下)
    2187 2经常增删改的表
    2188 3数据列包含太多重复数据(国籍)
    2189 
    2190 
    2191 ##性能查询
    2192 用法 :explain sql语句;
    2193 作用 : 1表的读取顺序            id
    2194     2数据读取操作的操作类型        select_type
    2195     3哪些索引可以使用
    2196     4是哪索引被实际使用
    2197     5表之间的引用
    2198     6每张表有多少行被优化器查询
    2199     
    2200     id、select_type、table、type、possible_key、key_len、ref、rows、extra
    2201 
    2202 id :id相同时,table从上往下执行;存在子查询时,id不同,id值越大,越先执行。
    2203     表子查询的select_type值为derived;
    2204 select_type:SIMPLE  PRIMARY  SUBQUERY  DERIVED  UNION  UNION RESULT
    2205     SIMPLE : 不包含子查询和union
    2206     PRIMARY:主查询,最外层 ,最后执行
    2207     SUBQUERY:子查询
    2208     DERIVED:表子查询
    2209     UNION:union后面的表的s_t为union
    2210     UNION RESULT:从union表获取结果的select
    2211 table:    显示这一张行数据是关于哪张表的
    2212 type: All  index  range  ref  eq_ref  const,system  Null
    2213     显示查询使用了何种类型,由好到坏依次为:
    2214     system>const>eq_ref>ref>range>index>All****************
    2215     -----------------------------------------------------------------
    2216     system:系统表,只有一行数据,const的特例,忽视掉
    2217     const:表示通过索引一次就找到了,用于比较primary和unique索引
    2218         因为只匹配一行数据,如where查主键的一个值
    2219     eq_ref:唯一性索引扫描,对于每一个索引键,表中只有一条记录与之匹配
    2220         explain select * from e ,d where e.id=d.id;
    2221         #e.id的每个值在d.id中只出现一次
    2222 ???ref:非唯一性索引扫描,返回匹配某个单独值的所有行(符合条件的多行)
    2223         explain select * from employees where job_id='AD_VP';
    2224     range:只检索给定范围的行使用一个索引来选择行,可以列显示使用哪个索引
    2225         between and >  <  in
    2226         explain select * from employees where `employee_id` between 100 and 105;
    2227     index:full index scan.与all的区别在于index只遍历索引数
    2228         explain select `employee_id` from employees;
    2229     full:遍历全表
    2230     
    2231 ********一般要求出现All以后的百万级查询,必须优化。一般到range,更好为ref
    2232 
    2233 possible_keys:显示可能应用在这张表的索引,一个或者多个(但不一定被查询实际使用)
    2234 key:实际使用的索引 【查询中若使用了覆盖索引,则该索引仅出现在key列表中】
    2235     【覆盖索引:用c1、c2建索引,查询为select c1,c2 from ..;】
    2236 key_len:索引中使用的字节数,可通过该值计算  查询中使用的索引的长度。在不损失精度
    2237      的情况下,【长度越短越好】。该值为索引字段的最大可能长度,【并非实际使用长度】
    2238 ???     即key_len是根据表计算而得,不是通过表内检索出来的
    2239 ref:显示索引的哪一列被使用了,如果可能的话,【是一个常数】
    2240 rows:根据 表统计信息 及索引选用情况,大致估算出找到所需记录要读取的行数,越小越好
    2241 extract:包含不合适在其他列中显示但十分重要的额外信息;
    2242        #using filesort:没有用索引进行排序,使用了一个外部索引【九死一生】
    2243      假设假设索引为ind_t_a_c_b。
    2244      select * from table t where t.a='*' order by t.c;则为using filesort
    2245      select * from table t where t.a='*' order by t.b;则不为using filesort
    2246      select * from table t where t.a='*' order by t.b,t.c;也不为using filesort
    2247        #using temporary 使用了临时表保存中间结果,MYsql对查询结果排序时使用临时表
    2248         常见于order by 和 group by【十死无生】
    2249        #using index 查询中使用了覆盖索引,【效率不错】 
    2250       同时出现了using where 表明索引被用来执行索引键值的查找(where 后面的列被用于建索引)
    2251           没出现using where表明索引中的列只用来select,没进行where
    2252        #using where 使用了where
    2253        #using join buffer 使用了连接缓存,配置文件里的using buffer调大
    2254        #impossible  where :where子句的值总是false,不能用来获取任何元组
    2255        #selec table optimized away:在没有group by子句的情况下,基于索引优化min/max
    2256        #distinct:优化distinct操作,在找到第一匹配的元组后即停止找同样的动作
    2257        
    2258     
    2259  */    
    2260 EXPLAIN 
    2261 SELECT id FROM(
    2262 SELECT a.id FROM admin a
    2263  UNION
    2264  SELECT b.id FROM beauty b) c ;
    2265  EXPLAIN
    2266  SELECT a.id FROM admin a
    2267  UNION
    2268  SELECT b.id FROM beauty b;
    2269  EXPLAIN SELECT * FROM admin ORDER BY PASSWORD;
    2270  
    2271 /*
    2272 索引优化
    2273 
    2274 */
    2275 ##案例1 单表索引优化
    2276 #category为1,comments>1,views最多的article_id
    2277 USE test;
    2278 CREATE TABLE IF NOT EXISTS article(
    2279     id INT(10)         UNSIGNED   NOT NULL    PRIMARY KEY    AUTO_INCREMENT,
    2280     author_id INT(10)       UNSIGNED   NOT NULL,
    2281     categoryid INT(10)     UNSIGNED   NOT NULL,
    2282     views INT(10)          UNSIGNED   NOT NULL,
    2283     comments INT(10)     UNSIGNED   NOT NULL,
    2284     title  VARBINARY(255)            NOT NULL,
    2285     content TEXT                NOT NULL 
    2286 );
    2287 
    2288 INSERT INTO article(`author_id`,`categoryid`,`views`,`comments`,`title`,`content`) 
    2289 VALUES
    2290     (1,1,1,1,'1','1'),
    2291     (2,2,2,2,'2','2'),
    2292     (3,3,3,3,'3','3'),
    2293     (4,4,4,4,'4','4');
    2294 #情况一:无索引。!type为all,extra提示using filesort
    2295 EXPLAIN  SELECT * FROM article WHERE categoryid =1 AND comments >1 
    2296                    ORDER BY views DESC LIMIT 1;
    2297 #情况二:按序建索引ccv.用到了索引,type为range,但是仍使用了文件内排序
    2298 #原因为comments为范围查询,sql无法利用索引再对后面的views进行检索。
    2299 #即range类型查询字段后面的索引无效
    2300 CREATE INDEX inx_article_ccv ON article(categoryid,comments,views);
    2301 EXPLAIN  SELECT * FROM article WHERE categoryid =1 AND comments >1 
    2302                    ORDER BY views DESC LIMIT 1;
    2303 #情况三:符合索引ca_v,type为ref,无文件内排序
    2304 DROP INDEX inx_article_ccv ON article;
    2305 CREATE INDEX inx_article_cv ON article(categoryid,views);
    2306 EXPLAIN  SELECT * FROM article WHERE categoryid =1 AND comments >1 
    2307                    ORDER BY views DESC LIMIT 1;
    2308 ##案例2:两表索引优化,左拼给右表加索引。
    2309 USE myemployees;
    2310 EXPLAIN SELECT * FROM employees e LEFT JOIN departments d 
    2311 ON e.`department_id`=d.`department_id`;
    2312 SHOW INDEX FROM `departments`;
    2313 ##案例3:三表连接,用小表驱动大表,索引建立在left 或 right 后面的
    2314 
    2315 
    2316 ##索引失效的原因:
    2317 /*
    2318 1全职匹配我的最爱
    2319 
    2320 2最佳左前缀法则********
    2321     复合索引要遵守该法则,查询应该从索引的最左前列开始,并且不跳过索引的列
    2322     create index stu_1_2_3 on student(`studentno`,`studentname`,`loginpwd`);
    2323     explain select * from student where studentno='S001' and studentname = '张三封' and `loginpwd`='8888';
    2324     explain select * from student where studentno='S001' and loginpwd = '8888';
    2325     explain select * from student where  loginpwd = '8888';##第一个字段不能丢失
    2326 
    2327 3不在索引列上做任何操作(计算、函数、(自动或者手动)的类型转换),导致索引失效,全表扫描
    2328 
    2329 4储存引擎不能使用索引中范围条件右边的列
    2330 create index table.a_b_c on table(a,b,c)
    2331 select * from table where a='' and b>X and c=''; #用不到c,但是
    2332 select * from table where a='' and b like 'xx%' and c='';#能用到c
    2333 
    2334 5尽量使用覆盖索引
    2335 
    2336 6mysql在使用非等于时(> < !=),无法使用索引,全表扫描
    2337 
    2338 7is null ,is not null 也无法使用索引
    2339 
    2340 8like以通配符开始,mysql无法使用索引,全表扫描,
    2341     比如select * ...like '%xx'不推荐,而like 'xx%'则使用了索引,type为range
    2342     若使用like '%xx%',需要使用覆盖索引,
    2343     即索引包含name时,select name ... like '%xx%';
    2344     #select使用*或者非索引列字段也不行
    2345 
    2346     like 'kk%',虽然也是range,但是与>x 不同,
    2347     like后面的等值条件还能用(显示在len上), >x后面的则通通失效
    2348 
    2349 9字符串不加单引号,mysql无法使用索引,全表扫描
    2350 
    2351 10少用or,用or连接时索引会失效
    2352 
    2353 总结:
    2354 
    2355 列只和建索引的书写顺序有关:比如index 123,where 1='' and 2='' and 3=''
    2356                     ===where 2='' and 3='' and 1=''
    2357                 where 1='' and 2> and 3=
    2358                 ==where 1='' and 3= and 2>
    2359 where有order,group时  :where 1= and 3= order by 2
    2360             ==where 1= and order by 2
    2361             ≈where 1= order by 2,3
    2362             但是 where 1= order by 3,2 (出现内排序,group出现temporary)
    2363             但是where 1= and 2= order by 3,2无内排序,因为2定值了
    2364             
    2365             但是 where 1= and 2= order by 3
    2366             !==where 1= order by 3(出现内排序using filesort)
    2367 
    2368 范围查询与order by结合
    2369 index 12
    2370 where 1> order by 1 优
    2371 where 1> order by 1,2 优
    2372 where 1= order by 2 优
    2373 where 1> order by 2  内排序 (理解索引的内涵)
    2374 where 1> order by 2,1 内排序 (排好序  的快速查找数据结构)
    2375 order by a acs,b desc,内排序(order by 默认升序,同升同降无内排序)
    2376 
    2377 group by :同order by,但能用where就不用having
    2378 
    2379 提高order by 的方法:
    2380 1 使用order by大忌使用select * ,应该只查询需要的字段
    2381   1.1当查询的字段的大小总和<max_length_for_sort_data而且排序字段不是
    2382     text/BLOB时,会使用改进算法--单路排序,否则使用对路排序,速度慢
    2383   1.2单路多路都可能超过sort_buffer的容量(单路可能性更大),超出后会创建temporary,导致慢速
    2384 
    2385 2尝试提高sort_buffer_size
    2386 3尝试提高max_length_for_sort_data,但是设置太高,容易超过sort_buffer_size
    2387 
    2388 
    2389 
    2390 口诀:
    2391 全职匹配我最爱,最左点缀要遵守
    2392 带头大哥不能死,中间兄弟不能断
    2393 索引列上少计算,范围之后全失效
    2394 like百分写最右,覆盖索引不写星
    2395 不等空值还有or,索引失效要少用
    2396 var引号不可丢 ,SQL高级也不难
    2397 */
    2398 
    2399 /*查询截取分析
    2400 
    2401 1至少跑一天,观察,看看生产的慢sql情况
    2402 
    2403 2开启慢查询日志,设置阈值:比如超过5秒的就是慢sql,并将其抓取出来
    2404 
    2405 3explain+慢sql分析
    2406 
    2407 4show profile
    2408 
    2409 5运维经理或DBA进行数据库服务器的参数调优
    2410 
    2411 总结:     1慢查询的开启并捕获
    2412     2explain+慢sql分析
    2413     3show profile查询sql在MySQL服务器里面的执行细节和生命周期情况
    2414     4sql数据服务器的参数调优
    2415     
    2416 理解小表驱动大表:
    2417 
    2418 A表数量>>B表
    2419 当:【select * from a where a.id in (select id from b)】as WAYIN
    2420     的执行顺序为:
    2421     1 select id from b
    2422     2 select * from a where a.id=b.id
    2423 此时的执行效率 in> exists
    2424 
    2425 A表数量<<B表
    2426 当:【select * from a where exists (select 1 from b where a.id =b.id)】as WAYEX
    2427     的执行顺序为
    2428     1 select * from a
    2429     2 select id from a.id=b.id
    2430 此时的执行效率 exists>in
    2431 
    2432 【exists语法为:
    2433 exists子查询中会忽略的select后面的查询列表,所以可以写1 ,'x'等常量值
    2434 
    2435     1 先查出主查询的全部数据(小表),
    2436     2 然后根据子查询(大表)得到的布尔向量决定小表数据的去留】
    2437 
    2438 ***总结:小表驱动大表时,即A表<<B表,使用WAYEX。
    2439 
    2440 */
    2441 
    2442 /*慢查询日志
    2443 show variables like '%slow_query%';
    2444 
    2445 set global slow_query_log =1 ;#开启慢查询日志
    2446     
    2447 show variables like '%long_query_time%';#默认时间>10s为慢sql
    2448 
    2449 set global long_query_time=3;#设置阈值为3,查看该值需在新会话查看,非新查询编辑器
    2450 set global slow_query_log_file = 'slow.log';#设置慢查日志的文件位置
    2451 
    2452 select sleep(4); #若执行超过阈值的sql会在慢查询中显示
    2453 
    2454 show global status like '%show_queries%';#显示当前系统中较慢的sql 条数
    2455 
    2456 */
    2457 
    2458 /*show profile
    2459 show variables like '%profiling%';
    2460 
    2461 set profiling = on;
    2462 
    2463 show profiles;
    2464 
    2465 show profile cpu, block io for query 17;#一条sql内部执行的完整生命周期
    2466 
    2467 #如果status出现以下条目,降低速度
    2468 1 coverting HEAP to MyISAM :查询结果太大,内存不够,往磁盘上搬了
    2469 2 creating tpm table :创建临时表,[拷贝数据到临时表][用完再删除]
    2470 3 cooying to tmp table on disk :把内存中临时表复制到磁盘。危险!! 
    2471 4 locked
    2472 */
    2473 
    2474 /*全局查询日志:#不要在生产环境开启该功能
    2475 
    2476 set global general_log ;
    2477 set global log_output='TABLE';
    2478 select * from  my.general_log;
    2479 
    2480 */
    2481 
    2482 /*数据库锁理论
    2483 锁是计算机协调多个进程或线程并发访问某一资源的机制
    2484 
    2485 在数据库锁中,除传统的计算资源(CPU,RAM,IO)的征用以外,数据也是一种供许多用户共享的资源。
    2486 如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库
    2487 并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。
    2488 
    2489 表锁分类:
    2490 #从对数据操作的类型:
    2491         1读锁(共享锁):针对同一份数据,多个读操作可以同时进行,不会互相影响
    2492             (会话1给表1上读锁,能读表1,不能改表1,不能读表2)
    2493             (会话2         能读表1,改表1阻塞,能读表2)    
    2494         2写锁(排它锁):当前写锁没有完成之前,它会阻断其他写锁和读锁
    2495             (会话1给表1上写锁,能读表1, 能改表1, 不能读表2)
    2496             (会话2能读表2,读表1发生阻塞,改表1更慢)
    2497         总结:读锁阻塞改表,写锁阻塞读写
    2498 show open tables; #显示没上锁的表
    2499 lock table 表1 read, 表2 write; #表1读锁,表2写锁
    2500 unlock tables; #解锁所有的表
    2501 show status like 'table%';
    2502 
    2503 行锁:只在事务中,对行增删改时,导致某一行锁定,另一会话阻塞增删改
    2504 行锁变表锁:varchar类型的 值为数字的 字段,没加引号,导致该列都被行锁,变成表锁
    2505 
    2506 set autocommit=0;
    2507 select * from table where id=x for update;#强制锁定一行
    2508 commit;#直到会话1结束,会话2才能读、写
    2509 */
    2510 DELIMITER ;
    复制代码
    Valar morghulis
    标签: sql
    <div id="blog_post_info">
    
    0
    0
    <div class="clear"></div>
    <div id="post_next_prev">
    
    <a class="p_n_p_prefix" href="https://www.cnblogs.com/super-yb/p/12337767.html">« </a> 上一篇:    <a title="发布于 2020-02-20 22:16" href="https://www.cnblogs.com/super-yb/p/12337767.html">word--公式添加编号</a>
    <br>
    <a class="p_n_p_prefix" href="https://www.cnblogs.com/super-yb/p/12703672.html">» </a> 下一篇:    <a title="发布于 2020-04-15 10:37" href="https://www.cnblogs.com/super-yb/p/12703672.html">R语言--倾向性评分matchit</a>
    
    posted on 2020-04-14 17:32  be·freedom  阅读(120)  评论(0编辑  收藏
    <!--done-->
    
  • 相关阅读:
    application/json 四种常见的 POST 提交数据方式
    物联网应用中实时定位与轨迹回放的解决方案 – Redis的典型运用(转载)
    C#的四种Timer介绍
    用python绘制趋势图
    Python 图形界面元素
    python 异常和弹出框
    python爬虫
    python文件操作
    GUI输入数据并保存
    图形界面+声音播放
  • 原文地址:https://www.cnblogs.com/tuihou/p/12831245.html
Copyright © 2011-2022 走看看