zoukankan      html  css  js  c++  java
  • Python学习之数据库

    9.6 表的查询

    【结构】select distinct 字段1,字段2 from 表名 where 条件 group by 字段 having 筛选 order by 字段 limit 限制条数

    【关键字优先级】from > where > group by > having > select/ distinct > order by > limit

    【执行顺序】从from这里找到待检索的表格 --》拿着where指定的约束条件,去表中取数据 --》 将取出的记录通过group by进行分组 --》 如果没有group by则整体作为一组 --》 将分组数据进行having过滤 --》执行select 并 distinct去重 --》 将结果按照条件order by 排序 --》 限制结果的显示条数

    单表查询

    以例为实,我招聘了一堆LOL英雄为我打工,来看一下
    # 建表
    create table employee(
    id int not null unique auto_increment,
    emp_name varchar(20) not null,
    sex enum('male','female') not null default 'male', #默认是male
    age int(3) unsigned not null default 24,  # 默认24
    hire_date date not null,
    post varchar(50),
    post_comment varchar(100),
    salary double(15,2),
    office int, # 一个部门的一个办公室
    depart_id int
    );
    
    
    # 插入数据
    insert into employee(emp_name,sex,age,hire_date,post,salary,office,depart_id) values
    ('泰达米尔','male',18,'20170301','院长',7300.33,401,1), #以下是教学部
    ('德鲁伊','male',78,'20150302','实战教练',1000000.31,401,1),
    ('塞恩','male',81,'20130305','实战教练',8300,401,1),
    ('乌迪尔','male',73,'20140701','实战教练',3500,401,1),
    ('布里茨','male',28,'20121101','实战教练',2100,401,1),
    ('迦娜','female',18,'20110211','实战教练',9000,401,1),
    ('潘森','male',18,'19000301','实战教练',30000,401,1),
    ('凯南','male',48,'20101111','实战教练',10000,401,1),
    
    ('索拉卡','female',48,'20150311','商务',3000.13,402,2),#以下是商务部
    ('莎娜','female',38,'20101101','商务',2000.35,402,2),
    ('卡尔玛','female',18,'20110312','商务',1000.37,402,2),
    ('艾希','female',18,'20160513','商务',3000.29,402,2),
    ('艾瑞莉娅','female',28,'20170127','商务',4000.33,402,2),
    
    ('金属大师','male',28,'20160311','教学顾问',10000.13,403,3), #以下是教学顾问
    ('武器大师','male',18,'19970312','教学顾问',20000,403,3),
    ('月光女神','female',18,'20130311','教学顾问',19000,403,3),
    ('太阳女神','male',18,'20150411','教学顾问',18000,403,3),
    ('战争女神','female',18,'20140512','教学顾问',17000,403,3)
    
    

    简单查询

    # 常规查询
    select * from 表名;   # 显示表中所有数据
    select 字段名 from 表名;   # 显示表中某一列的数据
    select 字段1,字段2... from 表名;  #  显示表中某几列的数据
    

    【注意】select与from是单独的语句

    # 去重查询
    select distinct 字段名 from 表名;
    
    # 联合去重
    select distinct 字段1,字段2 from 表名;
    
    mysql> select distinct post from employee;
    mysql> select distinct sex,post from employee;
    
    # 添加四则运算
    select 字段1,字段2*12 from 表名;  # 四则运算还是数值类型较多
    
    mysql> select emp_name,salary*12 from employee;
    
    # 添加显示元素,字符串相加
    select concat('姓名:',字段名)  from 表名;
    
    # 添加显示元素,字符串拼接,对字段中间以|分隔
    select concat_ws('分隔符',字段1,字段2....)  from 表名;
    
    # as重命名,as可以省略
    select concat('姓名:',字段名) as 新命名 from 表名  ;
    
    mysql> select concat ('name',emp_name) as name from employee;
    mysql> select concat_ws('|',emp_name,salary*12) as annual_salary from employee;
    
    

    as用的挺多

    # case语句  一定是有一个开始case和一个结束end
    select(
    	case
    	when 字段的条件 then concat(字段)
    	when 条件 then  字段
    	else 
    		字段
    	end
    ) as 新的命名
    
    mysql> select (
        -> case
        -> when post = '院长 ' then concat ('院长是',emp_name,'!')
        -> when post = '实战教练' then concat (emp_name,'是',post)
        -> when post = '商务' then concat (emp_name,'是可爱的知心小姐姐')
        -> else  concat (emp_name,'是大神')
        -> end
        -> ) as infomation from employee;
    
    

    select 之后可以跟字段(一个、多个、*)、调用函数、四则运算、去重、条件的判断

    where 条件

    条件名称 表达式 备注
    范围条件 > < < >  <= >= = !=
    包含条件 between A and B AB都包含在内
    包含条件 in/not in (A,B,C ) 值是A或B或C
    模糊查询 like/not like 表达式 通配符% _
    正则匹配 regexp 表达式 ^a以a开头 d+ 纯数字
    身份判断 is 、 is not null用is来判断
    逻辑判断 and or not

    【正则知识】

    模式 描述
    ^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 ' ' 或 ' ' 之后的位置。
    $ 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 ' ' 或 ' ' 之前的位置。
    . 匹配除 " " 之外的任何单个字符。要匹配包括 ' ' 在内的任何字符,请使用象 '[. ]' 的模式。
    [...] 字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。
    [^...] 负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。
    p1|p2|p3 匹配 p1 或 p2 或 p3。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。
    * 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。
    + 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
    {n} n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
    {n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。

    【特殊强调】like 模糊查询中 'A%' ---以A开头 '%A'---以A结尾 '%A%'---包含A
    '_A'---是_A %表示人一多的字符 _表示一个字符

    mysql> select emp_name from employee where emp_name like '%大师';
    
    mysql> select emp_name,age,salary from employee where salary in (10000 ,9000 ,30000 );
    
    mysql> select * from employee where  post_comment is  null;
    

    【实战练习】

    # 查出所有员工的名字,薪资,格式为 <名字:德鲁伊>    <薪资:10000000000>
    mysql> select concat('姓名:',emp_name,'>   <','薪资:',salary) from employee;  
       
    # 查出所有的岗位(去掉重复)
    mysql> select distinct post from employee;
    
    # 查出所有员工名字,以及他们的年薪,年薪的字段名为annual_year
    mysql> select emp_name,salary*12 as annual_year from employee;
    
    # 查看岗位是 实战教练 的员工姓名、年龄
    mysql> select emp_name,age from employee where post = '实战教练';
    
    # 查看岗位是 实战教练 且年龄大于30岁的员工姓名、年龄
    mysql> select emp_name,age from employee where post = '实战教练' and age>30;
    
    # 查看岗位是 实战教练 且薪资在9000-10000范围内的员工姓名、年龄、薪资
    mysql> select emp_name,age,salary from employee where post = '实战教练' and salary between 9000 and 10000;
    
    # 查看岗位描述不为NULL的员工信息
    mysql> select * from employee where post  is not null;
    
    # 查看岗位是 实战教练 且薪资是10000或9000或30000的员工姓名、年龄、薪资
    mysql> select emp_name,age,salary from employee where post = '实战教练' and salary in (10000,9000,30000);
    
    # 查看岗位是 实战教练 且薪资不是10000或9000或30000的员工姓名、年龄、薪资
    mysql> select emp_name,age,salary from employee where post = '实战教练' and salary not in (10000,9000,30000);
    
    # 查看岗位是 教学顾问 且名字是大师结尾的员工姓名、年薪
    mysql> select emp_name,salary*12 from employee where post = '教学顾问' and  emp_name like '%大师';
    
    

    分组Group By

    • 根据某一个重复率比较高的字段进行的分组,顺便数据去重;
    • 对于字段是unique的字段,使用分组是没有意义的
    group_concat()
    SELECT 字段1 GROUP_CONCAT (字段2) FROM 表名 GROUP BY 字段1
    

    group_concat(字段2)显示组内详情信息 只用来显示最后结果,不做他用,非必选项

    【实例】

    #  通过post进行分组,查看学校一共多少个部门
    mysql> select post from employee group by post;
    +--------------+
    | post         |
    +--------------+
    | 商务         |
    | 实战教练     |
    | 教学顾问     |
    | 院长         |
    +--------------+
    
    # 按post进行分组,查看所有信息
    mysql> select * from employee group by post;
    +----+--------------+--------+-----+------------+--------------+--------------+------------+--------+-----------+
    | id | emp_name     | sex    | age | hire_date  | post         | post_comment | salary     | office | depart_id |
    +----+--------------+--------+-----+------------+--------------+--------------+------------+--------+-----------+
    |  9 | 索拉卡       | female |  48 | 2015-03-11 | 商务         | NULL         |    3000.13 |    402 |         2 |
    |  2 | 德鲁伊       | male   |  78 | 2015-03-02 | 实战教练     | NULL         | 1000000.31 |    401 |         1 |
    | 14 | 金属大师     | male   |  28 | 2016-03-11 | 教学顾问     | NULL         |   10000.13 |    403 |         3 |
    |  1 | 泰达米尔     | male   |  18 | 2017-03-01 | 院长         | NULL         |    7300.33 |    401 |         1 |
    +----+--------------+--------+-----+------------+--------------+--------------+------------+--------+-----------+
    
    # 【注意】虽然是按post进行的分组但是,显示的是不同post组的第一条记录
    
    # 按post进行分组,查看姓名
    mysql> select post,emp_name from employee group by post;
    +--------------+--------------+
    | post         | emp_name     |
    +--------------+--------------+
    | 商务         | 索拉卡       |
    | 实战教练     | 德鲁伊       |
    | 教学顾问     | 金属大师     |
    | 院长         | 泰达米尔     |
    +--------------+--------------+
    
    # 如果想要显示组内的成员情况,就需要借助 group_concat()来实现
    # 按post进行分组,查看组内成员姓名
    mysql> select post,group_concat(emp_name) from employee group by post;
    +--------------+------------------------------------------------------------------+
    | post         | group_concat(emp_name)                                           |
    +--------------+------------------------------------------------------------------+
    | 商务         | 莎娜,艾瑞莉娅,艾希,卡尔玛,索拉卡                                 |
    | 实战教练     | 凯南,潘森,迦娜,布里茨,乌迪尔,塞恩,德鲁伊                         |
    | 教学顾问     | 太阳女神,月光女神,武器大师,金属大师,战争女神                     |
    | 院长         | 泰达米尔                                                         |
    +--------------+------------------------------------------------------------------+
    
    
    聚合函数

    分组之后就不能对某一条数据进行操作,对数据的操作要以组为单位,可以使用聚合函数:

    聚合函数 功能
    count 组内计数
    max 求组内最大值
    min 求组内最小值
    avg 求组内平均值
    sum 组内求和

    【实例】

    # 以post进行分组,并显示每组有多少个成员
    mysql> select post,count(id) from employee group by post;
    +--------------+-----------+
    | post         | count(id) |
    +--------------+-----------+
    | 商务         |         5 |
    | 实战教练     |         7 |
    | 教学顾问     |         5 |
    | 院长         |         1 |
    +--------------+-----------+
    
    # 查看每组的平均工资
    mysql> select post,avg(salary) from employee group by post;
    +--------------+---------------+
    | post         | avg(salary)   |
    +--------------+---------------+
    | 商务         |   2600.294000 |
    | 实战教练     | 151842.901429 |
    | 教学顾问     |  16800.026000 |
    | 院长         |   7300.330000 |
    +--------------+---------------+
    
    # 查看每组的工资最大值
    mysql> select post,max(salary) from employee group by post;
    
    
    having 过滤

    对分组后的数据进行筛选,条件是限制在组内成员的

    与where的区别是,where在分组之前对记录进行筛选,不能使用聚合函数;having是在分组之后对组进行筛选,可以使用聚合函数。

    【实例】

    # 查询各岗位内包含的员工个数小于2的岗位名、岗位内包含员工名字、个数
    mysql> select post,group_concat(emp_name),count(id) from employee group by post having count(id)<2;
    
    #  查询各岗位平均薪资大于10000的岗位名、平均工资
    mysql> select post,avg(salary) from employee group by post having avg(salary) > 10000;
    
    # 查询各岗位平均薪资大于10000且小于20000的岗位名、平均工资
    mysql> select post,avg(salary) from employee group by post having avg(salary) between 10000 and 20000;
    
    order by 排序

    【常用套路】

    ORDER BY 字段A; 按照A字段升序排序
    ORDER BY 字段A ASC; 按照A字段升序排序
    ORDER BY 字段A DESC; 按照A字段降序排序
    ORDER BY 字段A ,字段B; 按照A字段升序排序,如遇到重复,按照B升序排序
    ORDER BY 字段A ,字段B DESC; 按照A字段升序排序,如遇到重复,按照B降序排序
    ORDER BY 字段A DESC,字段B DESC; 按照A字段降序排序,如遇到重复,按照B降序排序

    【实例】

    # 查询所有员工信息,先按照age升序排序,如果age相同则按照hire_date降序排序
    mysql> select * from employee order by age asc,hire_date desc;
    
    # 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资升序排列
    mysql> select post,avg(salary) from employee group by post having avg(salary)>10000 order by avg(salary) asc;
    
    # 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资降序排列
    mysql> select post,avg(salary) from employee group by post having avg(salary)>10000 order by avg(salary) desc;
    
    limit
    • 取前N条记录;
    • 与order by 联合使用取前n名;
    • 分页显示

    【用法】

    • LIMIT m,n 表示从m+1项开始查询,取n条记录,当m没有赋值默认为0
    • LIMIT n offset m 是上式的另一种表达方式

    【实例】

    # 查看工资排名前五的员工
    mysql> select * from employee order by salary desc limit 0,5;
    

    9.7 表的修改

    # 修改表名
    # alter table 表名 rename 新表明
    
    # 添加新段
    # alter table 表名 add 新字段 类型(宽度) 约束;
    				# add 新字段 类型(宽度) 约束 after 字段A   # 在字段A后插入一列
    				# add 新字段 类型(宽度) 约束 first
    				
    # 删除段				
    # alter table 表名 drop 字段名;
    
    # 修改段名
    # alter table 表名 change 旧段名 新段名 类型(宽度) 约束;
    				# change name username char(12) not null
    				# change name name char(12) not null    # 只修改段属性
    				# change name name varchar(255) after id;   # 修改段属性和位置
    				
    # 修改段属性				
    # alter table 表名 modify 存在的字段 新类型(新宽度) 新约束;  
    				# modify name char(12) unique;
    				# modify name char(12) unique after id;
    

    9.8 数据操作

    增加

    # 增加
    # 增加一条数据
    # insert into 表名 value (属性1,属性2,...)  
    
    # 增加多条数据
    # insert into 表名 values (属性1,属性2,..),(属性1,属性2,..);
    
    # 定点插入数据  ******
    # insert into 表名(字段1,字段2) values (属性1,属性2);
    
    # 从其他表中复制相应的信息
    # insert into 表A(字段1,字段2) select (字段a,字段b) from 表B;
    

    删除

    delete from 表名  where 条件
    

    修改

    # update 表名 set 字段1=值1  where  条件
    # update 表名 set 字段1=值1,字段2=值2  where  条件
    
    仅供参考,欢迎指正
  • 相关阅读:
    拍皮球 (Java实现)
    余弦 (java实现)
    循环输出
    从1输出n位数字
    数值的整数次方
    旋转数组的最小数字
    简单使用栈实现队列
    重建二叉树
    链表逆序输出
    替代空格
  • 原文地址:https://www.cnblogs.com/jjzz1234/p/11311825.html
Copyright © 2011-2022 走看看