MySQL学习系列(二)

1.前文回顾

-- 50部门,工资大于8000的员工,按工资降序排列

SELECT id,
       fname,
       sal,
       dept_id
FROM emps
WHERE dept_id = 50
  AND sal>=8000
ORDER BY sal DESC;

 -- 电话号码tel包含'44',并把'44'改成'88';

SELECT id,
       fname,
       tel,
       replace(tel,'44','88'),
       dept_id
FROM emps
WHERE tel LIKE "%44%";

 -- 主管id(mgr_id)是100,120,122 的人数

SELECT count(*)
FROM emps
WHERE mgr_id in(100,120,122);

 -- 按主管id分组,求每个主管手下人数(去null)

SELECT mgr_id,
       count(*)
FROM emps
WHERE mgr_id IS NOT NULL
GROUP BY mgr_id;

2.having过滤

用来对多行函数结果进行过滤

(1).having 和 where 作用相同,都是条件过滤

(2).where 过滤普通条件,最早执行

(3).having 过滤多行函数结果,分组,求完多行函数后,才执行

(4).)having 跟在 group by 后面

-- 只有一个人的主管id
SELECT mgr_id,
       count(*) c
FROM emps
WHERE mgr_id IS NOT NULL
GROUP BY mgr_id HAVING c=1;
+--------+---+
| mgr_id | c |
+--------+---+
|    102 | 1 |
|    201 | 1 |
|    205 | 1 |
+--------+---+
3 rows in set (0.00 sec)

-- 平均工资小于等于5000的岗位
SELECT job_id,
       avg(sal) a
FROM emps
GROUP BY job_id HAVING a<=5000;
+----------+-------------+
| job_id   | a           |
+----------+-------------+
| AD_ASST  | 4400.000000 |
| PU_CLERK | 2780.000000 |
| SH_CLERK | 3215.000000 |
| ST_CLERK | 2785.000000 |
+----------+-------------+
4 rows in set (0.00 sec)

3.子查询

  • 条件子查询

一个查询的查询结果,作为另一个查询的过滤条件

select .. where a=(select ...)

(1).单值子查询: = > >= < <=

(2).多值子查询:
in

all 比最大值大

any 比最小值大

(3).多列子查询

where (a,b) in (select ...)

where (a,b) = (select ...)

-- 工资小于平均工资的员工
SELECT id,
       fname,
       sal
FROM emps
WHERE sal<
    (SELECT avg(sal)
     FROM emps);
+-----+-----------+----------+---------+
| id  | fname     | sal      | dept_id |
+-----+-----------+----------+---------+
| 100 | Steven    | 24000.00 |      90 |
| 103 | Alexander |  9000.00 |      60 |
| 108 | Nancy     | 12000.00 |     100 |
| 114 | Den       | 11000.00 |      30 |
| 121 | Adam      |  8200.00 |      50 |
| 145 | John      | 14000.00 |      80 |
| 200 | Jennifer  |  4400.00 |      10 |
| 201 | Michael   | 13000.00 |      20 |
| 203 | Susan     |  6500.00 |      40 |
| 204 | Hermann   | 10000.00 |      70 |
| 205 | Shelley   | 12000.00 |     110 |
+-----+-----------+----------+---------+

-- 只有一个人的部门,查询这些员工
-- 1. 按部门分组求人数,过滤只有一人的部门
-- 2. 用部门id过滤查询员工
SELECT id,
       fname,
       dept_id
FROM emps
WHERE dept_id IN
    (SELECT dept_id 
     FROM emps
     WHERE dept_id IS NOT NULL
     GROUP BY dept_id HAVING count(*) = 1);
+-----+----------+---------+
| id  | fname    | dept_id |
+-----+----------+---------+
| 200 | Jennifer |      10 |
| 203 | Susan    |      40 |
| 204 | Hermann  |      70 |
+-----+----------+---------+     
  • from子查询、行内视图

从查询的查询结果,在查询

select ... from (select ... from) t

-- 平均工资最低的工作岗位
-- 1.按job_id分组求平均工资
SELECT job_id,
       avg(sal) a
FROM emps
GROUP BY job_id;
-- 2.查询其平均工资最小值
SELECT min(a)
FROM
  (SELECT job_id,
          avg(sal) a
   FROM emps
   GROUP BY job_id) t;
-- 3.按最小工资过滤出job_id
SELECT job_id,
       avg(sal) a
FROM emps
GROUP BY job_id HAVING a=
  (SELECT min(a)
   FROM
     (SELECT job_id,
             avg(sal) a
      FROM emps
      GROUP BY job_id) t);

-- 手下人数最多的主管id
-- 1.按主管id分组求人数
SELECT mgr_id,
       count(*) c
FROM emps
WHERE mgr_id IS NOT NULL
GROUP BY mgr_id;
+--------+----+
| mgr_id | c  |
+--------+----+
|   NULL |  1 |
|    100 | 14 |
|    101 |  5 |
|    102 |  1 |
|    103 |  4 |
|    108 |  5 |
...
-- 2.求人数最大值max
SELECT max(c)
FROM
  (SELECT mgr_id,
          count(*) c
   FROM emps
   WHERE mgr_id IS NOT NULL
   GROUP BY mgr_id) t;
+--------+
| max(c) |
+--------+
|     14 |
+--------+
-- 3.通过max过滤出主管id
SELECT mgr_id,
       count(*) count
FROM emps
GROUP BY mgr_id HAVING count=
  (SELECT max(c)
   FROM
     (SELECT mgr_id,
             count(*) c
      FROM emps
      WHERE mgr_id IS NOT NULL
      GROUP BY mgr_id) t);
+--------+----+
| mgr_id | c  |
+--------+----+
|    100 | 14 |
+--------+----+

4.约束

  • 主键约束

数据表中对一行数据的唯一标识

(1).不重复
(2).不能是null值
(3).自动生成索引

一般使用“非业务数据”来作为主键

(1)自动增加 (2)随机生成

USE db1;
-- 主键约束
CREATE TABLE student( id int PRIMARY KEY, stu_num int, name varchar(20));

-- 插入数据
INSERT INTO student
VALUES(1,
       1,
       '张三');

-- Duplicate entry '1' for key 'PRIMARY'
INSERT INTO student
VALUES(1,
       2,
       '李四');
  • 自增主键

整数类型主键,可以设置自动生成自增的值

CREATE TABLE sutdent ( 
       id int PRIMARY KEY auto_increment,
       ....
       );
-- 修改表,把主键id修改成自增
-- 给student表主键设置自增
ALTER TABLE student MODIFY id int auto_increment;

获取刚产生的自增值

last_insert_id():只获得当前会话产生的自增值

INSERT INTO student(name)
VALUES('王五');
-- 查询自增值
select last_insert_id();
  • 外键约束

限制一个字段,只能取指定的主键字段中,存在的值

-- 新建学校表
CREATE TABLE school( id int PRIMARY KEY auto_increment, 
                     name varchar(20));
-- 修改学生表,添加外键字段sch_id
-- 引用school表的主键id
ALTER TABLE student add(sch_id int,
                        FOREIGN key(sch_id) REFERENCES school(id));
-- 添加两个学校
INSERT INTO school(name)
VALUES('ECUT'),('TEDU');  
-- 查询
SELECT * 
FROM school;
+----+------+
| id | name |
+----+------+
|  1 | ECUT |
|  2 | TEDU |
+----+------+
SELECT * 
FROM student;
+----+---------+--------+--------+
| id | stu_num | name   | sch_id |
+----+---------+--------+--------+
|  1 |       1 | 张三   |   NULL |
|  2 |    NULL | 王五   |   NULL |
|  3 |    NULL | 赵六   |   NULL |
|  4 |    NULL | qq     |   NULL |
|  5 |    NULL | aa     |   NULL |
+----+---------+--------+--------+
--学生1,2,3在ECUT
--学生4,5在TEDU
UPDATE student
SET sch_id =1
WHERE id IN(1,
            2,
            3);

UPDATE student
SET sch_id =2
WHERE id IN(4,
            5);

-- 查询
SELECT * 
FROM student;
+----+---------+--------+--------+
| id | stu_num | name   | sch_id |
+----+---------+--------+--------+
|  1 |       1 | 张三   |      1 |
|  2 |    NULL | 王五   |      1 |
|  3 |    NULL | 赵六   |      1 |
|  4 |    NULL | qq     |      2 |
|  5 |    NULL | aa     |      2 |
+----+---------+--------+--------+
  • 非空

null

  • 唯一

自动创建索引

  • 检查

1.设置检查条件,约束字段的取值

2.mysql不支持

3.mariadb 支持检查约束

5.多表连接查询(内连接)

两张表,按指定条件,连接成一张表

从连接的结果表中查询
[图片上传失败...(image-4c41d9-1533979159302)]

USE hr;
 -- 部门表
 
SELECT *
FROM depts;
+---------+----------------------+--------+--------+
| dept_id | dept_name            | mgr_id | loc_id |
+---------+----------------------+--------+--------+
|      10 | Administration       |    200 |   1700 |
|      20 | Marketing            |    201 |   1800 |
|      30 | Purchasing           |    114 |   1700 |
|      40 | Human Resources      |    203 |   2400 |
|      50 | Shipping             |    121 |   1500 |
|      60 | IT                   |    103 |   1400 |
|      70 | Public Relations     |    204 |   2700 |
|      80 | Sales                |    145 |   2500 |
|      90 | Executive            |    100 |   1700 |
|     100 | Finance              |    108 |   1700 |
|     110 | Accounting           |    205 |   1700 |
 ....
 -- 查询员工,显示员工部门名

SELECT e.id,
       e.fname,
       e.sal,
       d.dept_id,
       d.dept_name
FROM emps e,
     depts d
WHERE e.dept_id = d.dept_id;
+-----+-------------+----------+---------+------------------+
| id  | fname       | sal      | dept_id | dept_name        |
+-----+-------------+----------+---------+------------------+
| 200 | Jennifer    |  4400.00 |      10 | Administration   |
| 201 | Michael     | 13000.00 |      20 | Marketing        |
| 202 | Pat         |  6000.00 |      20 | Marketing        |
| 114 | Den         | 11000.00 |      30 | Purchasing       |
| 115 | Alexander   |  3100.00 |      30 | Purchasing       |
| 116 | Shelli      |  2900.00 |      30 | Purchasing       |
| 117 | Sigal       |  2800.00 |      30 | Purchasing       |
| 118 | Guy         |  2600.00 |      30 | Purchasing       |
| 119 | Karen       |  2500.00 |      30 | Purchasing       |
| 203 | Susan       |  6500.00 |      40 | Human Resources  |
| 120 | Matthew     |  8000.00 |      50 | Shipping         |
| 121 | Adam        |  8200.00 |      50 | Shipping         |
| 122 | Payam       |  7900.00 |      50 | Shipping         |
| 123 | Shanta      |  6500.00 |      50 | Shipping         |
...
-- 地区表

SELECT *
FROM locations;
+--------+------------------------------------------+-------------+---------------------+-------------------+------------+
| loc_id | street                                   | post        | city                | state             | country_id |
+--------+------------------------------------------+-------------+---------------------+-------------------+------------+
|   1000 | 1297 Via Cola di Rie                     | 00989       | Roma                | NULL              | IT         |
|   1100 | 93091 Calle della Testa                  | 10934       | Venice              | NULL              | IT         |
|   1200 | 2017 Shinjuku-ku                         | 1689        | Tokyo               | Tokyo Prefecture  | JP         |
|   1300 | 9450 Kamiya-cho                          | 6823        | Hiroshima           | NULL              | JP         |
|   1400 | 2014 Jabberwocky Rd                      | 26192       | Southlake           | Texas             | US         |
|   1500 | 2011 Interiors Blvd                      | 99236       | South San Francisco | California        | US         |
|   1600 | 2007 Zagora St                           | 50090       | South Brunswick     | New Jersey        | US         |
|   1700 | 2004 Charade Rd                          | 98199       | Seattle             | Washington        | US         |
...
-- 查询部门,显示部门的城市

SELECT d.dept_id,
       d.dept_name,
       l.city,
       l.state
FROM depts d,
     locations l
WHERE d.loc_id = l.loc_id;
+---------+----------------------+---------------------+------------+
| dept_id | dept_name            | city                | state      |
+---------+----------------------+---------------------+------------+
|      10 | Administration       | Seattle             | Washington |
|      20 | Marketing            | Toronto             | Ontario    |
|      30 | Purchasing           | Seattle             | Washington |
|      40 | Human Resources      | London              | NULL       |
|      50 | Shipping             | South San Francisco | California |
|      60 | IT                   | Southlake           | Texas      |
|      70 | Public Relations     | Munich              | Bavaria    |
|      80 | Sales                | Oxford              | Oxford     |
|      90 | Executive            | Seattle             | Washington |
|     100 | Finance              | Seattle             | Washington |
|     110 | Accounting           | Seattle             | Washington |
...
-- 查询部门,显示部门经理名

SELECT d.dept_id,
       d.dept_name,
       e.fname mgr
FROM depts d,
     emps e
WHERE d.mgr_id = e.id;
+---------+------------------+-----------+
| dept_id | dept_name        | mgr       |
+---------+------------------+-----------+
|      10 | Administration   | Jennifer  |
|      20 | Marketing        | Michael   |
|      30 | Purchasing       | Den       |
|      40 | Human Resources  | Susan     |
|      50 | Shipping         | Adam      |
|      60 | IT               | Alexander |
|      70 | Public Relations | Hermann   |
|      80 | Sales            | John      |
|      90 | Executive        | Steven    |
|     100 | Finance          | Nancy     |
|     110 | Accounting       | Shelley   |
+---------+------------------+-----------+
  • 自连接

一张表看做是两张表进行连接

-- 查询员工,显示员工主管名

SELECT e1.id,
       e1.fname,
       e1.sal,
       e2.fname mgr
FROM emps e1, emps e2
WHERE e1.mgr_id=e2.id;
+-----+-------------+----------+-----------+
| id  | fname       | sal      | mgr       |
+-----+-------------+----------+-----------+
| 101 | Neena       | 17000.00 | Steven    |
| 102 | Lex         | 17000.00 | Steven    |
| 103 | Alexander   |  9000.00 | Lex       |
| 104 | Bruce       |  6000.00 | Alexander |
| 105 | David       |  4800.00 | Alexander |
| 106 | Valli       |  4800.00 | Alexander |
| 107 | Diana       |  4200.00 | Alexander |
| 108 | Nancy       | 12000.00 | Neena     |
| 109 | Daniel      |  9000.00 | Nancy     |
| 110 | John        |  8200.00 | Nancy     |
| 111 | Ismael      |  7700.00 | Nancy     |
| 112 | Jose Manuel |  7800.00 | Nancy     |
| 113 | Luis        |  6900.00 | Nancy     |
...

6.外连接

外连接,非标准sql语法,每种数据库的外连接语法有所不同。
sql server :where a.id(+) = b.xid

oracle: where a.id *= b.xid;

mysql:没有相应的非标准sql语法.

-- 内连接格式
SELECT ...
FROM a
JOIN b on(a.id = b.xid)
JOIN c on(...);

-- 外连接格式

SELECT ...
FROM a
LEFT JOIN b on(a.id=b.xid)

SELECT ...
FROM a
RIGHT JOIN b on(a.id=b.xid)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容