python修炼——MySQL 查询!

MySQL 查询

查询以后会大量使用

SQL 语句没有标准答案,无非就是运行速度的问题

完整的select语句
select distinct *
from 表名
where ....
group by ... having ...
order by ...
limit start,count

--执行顺序为
from 表名
where ....
group by ...
select distinct *
having ...
order by ...
limit start,count
数据准备
-- 创建数据库
create database python_test charset=utf8;

-- 使用数据库
use python_test;

-- students表
create table students(
    id int unsigned primary key auto_increment not null,
    name varchar(20) default '',
    age tinyint unsigned default 0,
    height decimal(5,2),
    gender enum('男','女','中性','保密') default '保密',
    cls_id int unsigned default 0,
    is_delete bit default 0
);

-- classes表
create table classes (
    id int unsigned auto_increment primary key not null,
    name varchar(30) not null
);

-- 向students表中插入数据
insert into students values
(0,'小明',18,180.00,2,1,0),
(0,'小月月',18,180.00,2,2,1),
(0,'彭于晏',29,185.00,1,1,0),
(0,'刘德华',59,175.00,1,2,1),
(0,'黄蓉',38,160.00,2,1,0),
(0,'凤姐',28,150.00,4,2,1),
(0,'王祖贤',18,172.00,2,1,1),
(0,'周杰伦',36,NULL,1,1,0),
(0,'程坤',27,181.00,1,2,0),
(0,'刘亦菲',25,166.00,2,2,0),
(0,'金星',33,162.00,3,3,1),
(0,'静香',12,180.00,2,4,0),
(0,'郭靖',12,170.00,1,4,0),
(0,'周杰',34,176.00,2,5,0);

-- 向classes表中插入数据
insert into classes values (0, "python_01期"), (0, "python_02期");
查询
--消除重复行
--在 select 后面列前使用 distinct 可以消除重复行
select distinct1,... from 表名;
select distinct gender from students;


--条件查询
--比较运算符
--等于: =
--大于: >
--大于等于: >=
--小于: <
--小于等于: <=
--不等于: != 或 <> 
select ... from 表名 where ...
select * from students where id>3;

--逻辑运算符
--and:与   and 左边和右边的条件必须写全
select * form students where age>18 and age<18;
--or:或  
select * from students where age>18 or height>=180;
--not:非
--优先级  使用括号()   不变应万变
--优先级由高到低的顺序为:小括号,not,比较运算符,逻辑运算符
--and比or先运算,如果同时出现并希望先算or,需要结合()使用
select * from students where not (age>18 and gender=2);
select * from students where (not age<=18)  and gender=2;

--模糊查询
--like
--%表示任意多个任意字符
--_表示一个任意字符
select name from students where name like"__%";
--rlike 正则
select name from students where name rlike "^周.*伦$";


--范围查询
--in表示在一个非连续的范围内
-- not in 不非连续的范围之内
select * from students where age in (12,18,34);
select * from students where age not in (12,18,34);
--between ... and ...表示在一个连续的范围内
-- not between ... and ...表示不在一个连续的范围内
select * from students where age between 18 and 34;
select * from students where age not between 18 and 34;


-- 空判断
-- 判断空is null
--判断非空 is not null
select * from students where height is null;


--排序
-- order by 字段
-- asc从小到大排列,即升序
-- desc从大到小排序,即降序
select * from students where (age between 18 and 34) and gender=2 order by age;
select * from students where (age between 18 and 34) and gender=2 order by age desc;
select * from students where (age between 18 and 34) and gender=2 order by height desc,id desc;


--聚合函数
--count(*) 计算总行数 
select count(*) as 女性人数 from students where gender=2;
--max(列)  求此列的最大值
select max(height) from students where gender=2;
--min(列)  求此列的最小值
select min(height) from students where gender=2;
--sum()  求和
select sum(age) from students;
--avg()  求平均值
select avg(age) from students;
--round(数据,指定保留的位数)  四舍五入
--经验:银行相关的操作不要四舍五入。可以先乘再除
select round(avg(height), 2) from students where gender=1;


-- 分组
-- group by
-- group_concat(字段名) 可以作为一个输出字段来使用
-- 表示分组之后,根据分组结果,使用 group_concat() 来放置每一组的某字段的值的集合
-- group by + having
-- having  条件表达式:用来分组查询后指定一些条件来输出查询结果
-- having 的作用和 where 一样,但是 having 只能用于 group by
select * from students group by gender;
select gender,group_concat(name) from students group by gender having count(*)>2;
-- group by + with rollup
-- with rollup 的作用是:在最后新增一行,来记录当前列里所有记录的总和
select gender,count(*) from students group by gender with rollup;



-- 分页
-- limit start, count
--limit (第N页-1)*每个的个数, 每页的个数;
select * from students limit 0,2;


-- 连接查询
-- inner join ... on
-- select ... from 表A inner join 表B;
select * from students inner join calsses;
select students.name,classes.name from students inner join classes on students.cls_id=classes.id;
select s.name,c.name from students as s inner join classes as c on s.cls_id=c.id;
select c.name,s.* from students as s inner join classes as c on s.cls_id=c.id order by c.name,s.id;

select c.name,s.* from students as s inner join classes as c on s.cls_id=c.id order by c.name;
-- select .... form 表A left join 表B;
-- 左连接查询会以左边的表为主,查询的结果为两个表匹配到的数据,左表特有的数据,对于右表不存在的数据使用 null 填充
select * from students as s left join classes as c on s.cls_id=c.id;



--自关联
--数据准备
create table areas(
    aid int primary key,
    atitle varchar(20),
    pid int
);
source areas.sql;  -- 从 sql 文件中导入数据

select * from areas where pid is null;

select * from areas as province inner join areas as city on city.pid=province.aid having province.atitle="山东省";

select province.atitle,city.atitle from areas as province inner join areas as city on city.pid=province.aid having province.atitle="山西省";


--子查询
--主查询和子查询的关系
--子查询是嵌入到主查询中
--子查询是辅助主查询的,要么充当条件,要么充当数据源
--子查询是可以独立存在的语句,是一条完整的 select 语句
select * from students where age > (select avg(age) from students);

猜你喜欢

转载自blog.csdn.net/qyf__123/article/details/82192202