MySQL进阶操作

先建两个表

表-ren

+------+--------------+-------+--------------+----------+-------+
| p_id | p_name       | p_age | p_menpai     | p_leader | p_sal |
+------+--------------+-------+--------------+----------+-------+
| p001 | 张三丰       |   100 | 武当         | 0        | 10000 |
| p003 | 岳不群       |    40 | 华山         | 0        |  6500 |
| p002 | 张无忌       |    20 | 明教         | 0        |  8000 |
| p004 | 东方不败     |    35 | 日月神教     | 0        | 12000 |
| p005 | 令狐冲       |    21 | 华山         | p003     |  4000 |
| p006 | 林平之       |    18 | 华山         | p003     |  2000 |
| p007 | 左冷禅       |    50 | NULL         | 0        | 10000 |
| p008 | 张翠山       |    46 | 武当         | p001     | 10000 |
| p009 | 张远桥       |    55 | 武当         | p001     |  6500 |
+------+--------------+-------+--------------+----------+-------+

表-wei

+------+--------------+-----------+
| a_id | a_name       | a_add     |
+------+--------------+-----------+
| a001 | 嵩山         | 河南      |
| a002 | 华山         | 山西      |
| a003 | 武当         | 湖北      |
| a004 | 日月神教     | 黑木崖    |
+------+--------------+-----------+

  

聚合函数-max(),min(),sum(),avg()

用于查数据  使用聚合函数查出来的结果字段名是带有聚合函数的,使用as语句可以来更名

查一个字段的最大值

-- select max(字段) from 表名

select max(p_sal) from ren
-- max(p_sal)
-- 12000

查一个字段的最小值

select min(字段) from 表名

查一个字段的平均值

select avg(字段) from 表名

差一个字段的和

select sum(字段) from 表名

查有一个字段有多少数据

可以通过查主键来查有多少数据,查不到null

-- select count(字段) from 表名

select count(p_menpai) from ren
-- count(p_menpai)
-- 8
select count(p_id) from ren
-- count(p_id)
-- 9

分组 - 分组后使用条件不使用where 使用having

-- select 字段1 from 表名 group by 字段一
-- 以字段一进行分组,相同值为一组,可以给某一字段去重,可以分组调用聚合函数

select avg(p_sal),p_menpai from ren group by p_menpai 
-- 查每组的平均工资
-- avg(p_sal)    p_menpai 
-- 10000.0000    (null)
-- 4166.6667    华山
-- 12000.0000    日月神教
-- 8000.0000    明教
-- 8833.3333    武当

group_concat()--可以查询分组后字段中的项

如有下表

mysql> select * from student;
+-----+--------+----------+--------+
| sid | gender | class_id | sname  |
+-----+--------+----------+--------+
|   1 | 男     |        1 | 理解   |
|   2 | 女     |        1 | 钢蛋   |
|   3 | 男     |        1 | 张三   |
|   4 | 男     |        1 | 张一   |
|   5 | 女     |        1 | 张二   |
|   6 | 男     |        1 | 张四   |
|   7 | 女     |        2 | 铁锤   |
|   8 | 男     |        2 | 李三   |
|   9 | 男     |        2 | 李一   |
|  10 | 女     |        2 | 李二   |
|  11 | 男     |        2 | 李四   |
|  12 | 女     |        3 | 如花   |
|  13 | 男     |        3 | 刘三   |
|  14 | 男     |        3 | 刘一   |
|  15 | 女     |        3 | 刘二   |
|  16 | 男     |        3 | 刘四   |
+-----+--------+----------+--------+

用法

mysql> select group_concat(sname) from student group by class_id;
+-------------------------------------------+
| group_concat(sname)                       |
+-------------------------------------------+
| 理解,钢蛋,张三,张一,张二,张四             |
| 铁锤,李三,李一,李二,李四                  |
| 如花,刘三,刘一,刘二,刘四                  |
+-------------------------------------------+
3 rows in set (0.00 sec)

mysql> select group_concat(sname,gender) from student group by class_id;
+-------------------------------------------------------------+
| group_concat(sname,gender)                                  |
+-------------------------------------------------------------+
| 理解男,钢蛋女,张三男,张一男,张二女,张四男                   |
| 铁锤女,李三男,李一男,李二女,李四男                          |
| 如花女,刘三男,刘一男,刘二女,刘四男                          |
+-------------------------------------------------------------+
3 rows in set (0.00 sec)

mysql> select group_concat(sname),group_concat(gender) from student group by class_id;
+-------------------------------------------+-------------------------+
| group_concat(sname)                       | group_concat(gender)    |
+-------------------------------------------+-------------------------+
| 理解,钢蛋,张三,张一,张二,张四             | 男,女,男,男,女,男       |
| 铁锤,李三,李一,李二,李四                  | 女,男,男,女,男          |
| 如花,刘三,刘一,刘二,刘四                  | 女,男,男,女,男          |
+-------------------------------------------+-------------------------+

-- 删除重复内容

delete from ren where p_name in (
            select * from (select p_name from ren  GROUP BY p_name HAVING count(1)>1) as h)  -- 根据要查删除的字段分组,加条件得到有多个项的组名,重新命名,因为不能同时查和删
-- 删除数据并且保留符合条件的
delete from ren where p_name in (
            select * from (select p_name from ren  GROUP BY p_name HAVING count(1)>1) as h
        )
        and p_id NOT IN(
            select * from(select max(p_id) from ren GROUP BY p_name HAVING count(1)>1)  T
        ) -- 前面条件是找到有重复内容的组,后面的条件找到符合条件的项
-- 代码意义为 删除p_name中重复的项,保留p_id最大的项

去重

-- select distinct 字段 from 表名
-- 可以使用多个字段,用逗号隔开,两个字段对应的值一样才会去重

select distinct p_menpai from ren
-- 武当
-- 华山
-- 明教
-- 日月神教
-- (null)

分页

-- select * from 字段名 limit x,y
-- x表示起始位置的索引,y表示查几条

select p_id from ren limit 2,5
-- p_id 
-- p002
-- p004
-- p005
-- p006
-- p007

关于limit

-- limit实际上是扫描至索引位置,查询指定条数
-- 当指定位置非常靠后时,会耗费大量的时间
-- 线上常用的方式一个是限制页数
-- 二就是在页面中记录前后记录的ID,使用where筛选出数据在使用limit

多表联合查询

多个表须有关联才能进行查询

-- select * from 表1,表2 where 表1.字段=表2.字段 and
-- 一定要加条件,否则会出现笛卡尔乘积
-- 结果是符合两个表条件的表
select * from ren,wei where ren.p_menpai=wei.a_name

+------+--------------+-------+--------------+----------+-------+------+--------------+-----------+
| p_id | p_name       | p_age | p_menpai     | p_leader | p_sal | a_id | a_name       | a_add     |
+------+--------------+-------+--------------+----------+-------+------+--------------+-----------+
| p001 | 张三丰       |   100 | 武当         | 0        | 10000 | a003 | 武当         | 湖北      |
| p003 | 岳不群       |    40 | 华山         | 0        |  6500 | a002 | 华山         | 山西      |
| p004 | 东方不败     |    35 | 日月神教     | 0        | 12000 | a004 | 日月神教     | 黑木崖    |
| p005 | 令狐冲       |    21 | 华山         | p003     |  4000 | a002 | 华山         | 山西      |
| p006 | 林平之       |    18 | 华山         | p003     |  2000 | a002 | 华山         | 山西      |
| p008 | 张翠山       |    46 | 武当         | p001     | 10000 | a003 | 武当         | 湖北      |
| p009 | 张远桥       |    55 | 武当         | p001     |  6500 | a003 | 武当         | 湖北      |
+------+--------------+-------+--------------+----------+-------+------+--------------+-----------+

如果是多个表进行查询,每一个表必须和其他一个或多个表有关联

左连接

select * from 表1 left join 表2 on 表1.字段=表2.字段

注意:on 表示条件 专门配置 left join 来使用
特点:左表数据全要,右表的数据与左表数据相匹配则显示,不匹配则以NULL填充

select * from ren left join wei on  ren.p_menpai=wei.a_name

+------+--------------+-------+--------------+----------+-------+------+--------------+-----------+
| p_id | p_name       | p_age | p_menpai     | p_leader | p_sal | a_id | a_name       | a_add     |
+------+--------------+-------+--------------+----------+-------+------+--------------+-----------+
| p003 | 岳不群       |    40 | 华山         | 0        |  6500 | a002 | 华山         | 山西      |
| p005 | 令狐冲       |    21 | 华山         | p003     |  4000 | a002 | 华山         | 山西      |
| p006 | 林平之       |    18 | 华山         | p003     |  2000 | a002 | 华山         | 山西      |
| p001 | 张三丰       |   100 | 武当         | 0        | 10000 | a003 | 武当         | 湖北      |
| p008 | 张翠山       |    46 | 武当         | p001     | 10000 | a003 | 武当         | 湖北      |
| p009 | 张远桥       |    55 | 武当         | p001     |  6500 | a003 | 武当         | 湖北      |
| p004 | 东方不败     |    35 | 日月神教     | 0        | 12000 | a004 | 日月神教     | 黑木崖    |
| p002 | 张无忌       |    20 | 明教         | 0        |  8000 | NULL | NULL         | NULL      |
| p007 | 左冷禅       |    50 | NULL         | 0        | 10000 | NULL | NULL         | NULL      |
+------+--------------+-------+--------------+----------+-------+------+--------------+-----------+

右连接

与左连接相似

右表数据全要,左表的数据与右表数据相匹配则显示,不匹配则以NULL填充

-- select * from 表1 right join 表2 on 表1.字段=表2.字段

select * from ren RIGHT join wei on  ren.p_menpai=wei.a_name

+------+--------------+-------+--------------+----------+-------+------+--------------+-----------+
| p_id | p_name       | p_age | p_menpai     | p_leader | p_sal | a_id | a_name       | a_add     |
+------+--------------+-------+--------------+----------+-------+------+--------------+-----------+
| p001 | 张三丰       |   100 | 武当         | 0        | 10000 | a003 | 武当         | 湖北      |
| p003 | 岳不群       |    40 | 华山         | 0        |  6500 | a002 | 华山         | 山西      |
| p004 | 东方不败     |    35 | 日月神教     | 0        | 12000 | a004 | 日月神教     | 黑木崖    |
| p005 | 令狐冲       |    21 | 华山         | p003     |  4000 | a002 | 华山         | 山西      |
| p006 | 林平之       |    18 | 华山         | p003     |  2000 | a002 | 华山         | 山西      |
| p008 | 张翠山       |    46 | 武当         | p001     | 10000 | a003 | 武当         | 湖北      |
| p009 | 张远桥       |    55 | 武当         | p001     |  6500 | a003 | 武当         | 湖北      |
| NULL | NULL         |  NULL | NULL         | NULL     |  NULL | a001 | 嵩山         | 河南      |
+------+--------------+-------+--------------+----------+-------+------+--------------+-----------+

里连接 与多表联合相似

-- select * from 表1 inner join 表2 on 表1.字段=表2.字段

select * from ren inner join wei on  ren.p_menpai=wei.a_name

+------+--------------+-------+--------------+----------+-------+------+--------------+-----------+
| p_id | p_name       | p_age | p_menpai     | p_leader | p_sal | a_id | a_name       | a_add     |
+------+--------------+-------+--------------+----------+-------+------+--------------+-----------+
| p001 | 张三丰       |   100 | 武当         | 0        | 10000 | a003 | 武当         | 湖北      |
| p003 | 岳不群       |    40 | 华山         | 0        |  6500 | a002 | 华山         | 山西      |
| p004 | 东方不败     |    35 | 日月神教     | 0        | 12000 | a004 | 日月神教     | 黑木崖    |
| p005 | 令狐冲       |    21 | 华山         | p003     |  4000 | a002 | 华山         | 山西      |
| p006 | 林平之       |    18 | 华山         | p003     |  2000 | a002 | 华山         | 山西      |
| p008 | 张翠山       |    46 | 武当         | p001     | 10000 | a003 | 武当         | 湖北      |
| p009 | 张远桥       |    55 | 武当         | p001     |  6500 | a003 | 武当         | 湖北      |
+------+--------------+-------+--------------+----------+-------+------+--------------+-----------+

 union --- unionall

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。

请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列,每条 SELECT 语句中的列的顺序必须相同,不然会混乱。

select id,name from biao1 union select id2,name2 from biao2
+----+--------+
| id | name   |
+----+--------+
|  1 | 向北   |
|  2 | 杨枭   |
|  1 | 何年   |
|  2 | 何月   |
+----+--------+

select id2,name2 from biao2 union select id,name from biao1;
+-----+--------+
| id2 | name2  |
+-----+--------+
|   1 | 何年   |
|   2 | 何月   |
|   1 | 向北   |
|   2 | 杨枭   |
+-----+--------+

select id2,name2 from biao2 union select id from biao1;
-- ERROR 1222 (21000): The used SELECT statements have a different number of columns

  

posted @ 2017-12-08 18:03  瓜田月夜  阅读(136)  评论(0)    收藏  举报