SQL结构化查询语——之DQL语言

记忆思路:SQL的DQL语言select查询命令。
from从哪个表中where以什么条件select查询哪些列,order by是否基于某字段排序,limit # 输出多少行。
一、单表查询
1. 常用查询语法:

  1. SELECT 输出显示字段 FROM 表名
  2. 无条件查询语法:SELECT 指定输出的列 FROM 表名 ;
  3. 限制输出语法:SELECT 指定输出的列 FROM 表名 LIMIT 显示记录数 ;
  4. 条件查询语法:SELECT 指定输出的列 FROM 表名 WHRER 查询条件 ;
  5. 条件查询再排序:SELECT 指定输出的列 FROM 表名 WHRER 查询条件 order by 指定排序字段 [desc|asc];
  6. 条件查询并限制输出语法:SELECT 显示输出的列 FROM 表名 WHRER 查询条件 LIMIT 显示记录数 ;

2. SELECT过滤输出列:

  1. 实例一:输出显示表所有行与列,【代表所有列】
    SELECT
    FROM students; 查询students表的所有内容
  2. 实例二:输出显示字段以别名输出:【字段名 as 别名】注意as可以省略
    SELECT name as 姓名,age as 年龄 FROM vmlab;
    SELECT name 姓名,age 年龄 FROM vmlab;

3. WHERE过滤输出行:通过where限定过滤条件

  1. 算术操作符:+, -, *, /, %
  2. 逻辑操作符:NOT,AND,OR,XOR
  3. 比较操作符:=,<=>(相等或都为空), <>, !=(非标准SQL), >, >=, <, <=
    select from vmlab where age >=30;
    SELECT FROM students WHERE gender='m';查询所有男生
    SELECT
    FROM students WHERE id < 3; 查询students表中id字段值小于3的所有行的所有字段
    SELECT * FROM students WHERE id >=2 and id <=4;查询id大于等2小于等4的记录;

  4. 区间取值:BETWEEN minnum AND maxnum
    SELECT
    FROM students WHERE BETWEEN 2 AND 4;查询id大于等2小于等4的记录;
  5. in 明确指定值:
    select * from vmlab where classid in (1,3,6);
  6. 匹配空值与非空值 :is null、is not null
    select from vmlab where classid is null 匹配classid为空值的行
    select
    from vmlab where classid is not null 匹配classid为非空值的行
  7. 模糊匹配 like
    % 任意长度的任意字符 ,_ 任意单个字符
    SELECT * FROM students WHERE name LIKE 't%'; 基于模糊匹配查询name字段以字母t开头的所有记录

  8. 正则表达式匹配
    rlike:
    SELECT FROM students WHERE name RLIKE '.[lo].';基于正则匹配查询name字段包含字母l或o的记录
    REGEXP:
    SELECT
    FROM vmlab WHERE name REGEXP '^h';

4. 分组统计:
GROUP BY根据指定的条件对查询结果进行“分组”以用于做“聚合”运算,输出字段一般为:聚合计算的字段和计算结果。

  1. 常用的聚合函数:count()计数、avg() 平均值、max() 最大值 、min() 最小值、sum() 求和
  2. HAVING: 对分组聚合运算后的结果指定过滤条件。
  3. 例:
    select classid,gender,avg(age) from students group by classid,gender;
    select classid,gender,avg(age) from students group by classid,gender having classid is not null;
    5. 数据整形操作
    ORDER BY: 根据指定的字段对查询结果进行排序
  4. 升序:ASC(默认为升序)
    select distinct classid from students order by classid;
    select distinct classid from students order by classid asc;
  5. 降序:DESC
    select distinct classid from students order by classid desc;
  6. 过滤显示空值
    select distinct classid from students where classid is null;
  7. 过滤不显示空值;
    select distinct classid from students where classid is not null;
  8. 去除重复列 DISTINCT
    select distinct classid from students;
    select from t1 union select from t1;
  9. 为输出列定义别名
    SELECT id stuid,name as stuname FROM students 查询students表中stuid、stuname字段,并将name字段以别名stuname显示输出。

6. 限制输出:

  1. LIMIT [[offset,]row_count]:对查询的结果进行输出行数数量限制
    SELECT FROM students ORDER BY name DESC LIMIT 2; 按name字段做降序排列,并出输前2条记录
    SELECT
    FROM students ORDER BY name DESC LIMIT 3,5; 按name字段做降序排列,并从第3记录开始输出5条记录

7. 操作实例:

1. 实例一:计算students表中男女生平均年龄,思路:用group by对性别字段进行分组,然后用avg()函数对年龄字段求平均数,最后输出性别、年龄字段计算的平均数。

select gender,avg(age) from students group by gender;
2. 实例二:计算students表中每个班级的男女生平均年龄,思路:用group by先对班级字段进行分组,再对同班级的性别做分组,然后对年龄字段求平均烽,最后输出字段为班级、性别、年龄字段计算的平均数。

select classid,gender,avg(age) from students group by classid,gender;
select classid,gender,avg(age) from students group by classid,gender having classid is not null; having过滤班级为空的学生不统计。过滤条件having一定要用在group by之后,先做分组统计计算然后再做过滤。
select classid,gender,avg(age) from students where classid is not null group by classid,gender; where过滤班级为空的学生不统计。过滤条件where一定要用在group by之前,先做过滤,然后再做分组统计。
3. 实例三:分组统计完成后,用order by对指输出字段做排序,asc升序排列,desc降序排列。

select classid,gender,avg(age) from students where classid is not null group by classid,gender order by avg(age) asc; asc升序排列
select classid,gender,avg(age) from students where classid is not null group by classid,gender order by avg(age) desc; desc降序排列
4. 实例四:做完分组统计、升降序排列后,做限制输出,如仅输出前100条记录,即TOP100。

select classid,gender,avg(age) from students where classid is not null group by classid,gender order by avg(age) asc limit 5; 升序限制输出
select classid,gender,avg(age) from students where classid is not null group by classid,gender order by avg(age) desc limit 5; 降序限制输出
5. 实例五:利用输出字段别名定制输出表头

select classid as 班级,gender as 性别,avg(age) as 平均年龄 from students where classid is not null group by classid,gender order by avg(age) asc limit 5;
6.实列六:以班级为分组计算平均年龄,并显示平均年龄大于30,且班级ID大于3

select classid,avg(age) from students group by classid having avg(age) >30 and classid >3;

二、多表查询

  1. 子查询:查询语句中嵌入另一个查询语句,将子查询语句的结果做为父语句过滤条件或输入结果。
    select name,age from students where age >(select avg(age)from students);
  2. 纵向合并:利用union联合查询实现多表纵向合并,默认有去重功能,如果不想去重则可以用union all。
    必要条件:多个表之间的合并字段数据类型必须相同,在select后的输出字段书写顺序必须都一致。
    select * from teachers union select Stuid,name,age,Gender from students;
  3. 横向合并:思路先确定哪个是主表。
    a. 字段数是两个表选取字段之和
    b. 记录数是两个表记录做笛卡尔乘积,即两表记录相乘,所有记录字段交叉合并,主表的每条记录与副表的每条记录分别合并。
    select from students cross join teachers;
    select
    from students,teachers;
    select students.name,teachers.name,students.classid from students,teachers limit 10;输出指定字列,必须指定要指定输出哪个表的列。
    select students.name as 姓名,teachers.name as 老师,students.classid 班级 from students,teachers limit 10;用字段别名定制输出表头。
    select st.name as 姓名,te.name as 老师,st.classid 班级 from students as st,teachers as te limit 10;为表指定别名,然后再输写输出字段会更简洁,表一旦指定别名就必须使用。
  4. 内连接:inner join 取两个表的交集
    逻辑:基于两个表的某个或某些共有特性为依据横向合并两表,使两表内的记录基于某条件建立关联。如果不加合并条件就是做笛卡尔乘积合并。
    实例:
    select from students inner join teachers on students.teacherid=teachers.tid; 新式输写
    select
    from students as s,teachers as t where s.teacherid=t.tid order by stuid;旧式输写
    select s.Stuid,s.name,t.name,s.classid from students as s inner join teachers as t on s.teacherid=t.tid order by stuid; 基于表的别名定制输出字段。
    select s.Stuid as 学号,s.name as 姓名,t.name as 老师,s.classid as 班级 from students as s inner join teachers as t on s.teacherid=t.tid order by stuid;为输出字段定义别名达到定制输出表头的目录。
    复合条件合并:
    select from students as s inner join teachers as t on s.teacherid=t.tid and s.stuid >10;
    select
    from students as s inner join teachers as t on s.teacherid=t.tid where s.stuid >10;
    SQL结构化查询语——之DQL语言
  5. 外连接:
    逻辑:左右是相对概念,因此在合并前先确定哪个表为主表,主表所有记录将全部输出,被吞并的表为副 表,副表的记录会被横向合并到主表中。
    左外连接:设左侧为主表,所有记录将全部输出,右为副表,两表进行横向合并,将副表(右侧表)中符合合并条件的记录填写在主表(左侧表)的对应记录内,主表中其余记录不符合条件的副表,并根据需求定制输出显示字段。
    select from students as s left outer join teachers as t on s.teacherid=t.tid;
    左外连接特例:用where设置过滤条件,排除左右表具有某共同特性的记录,横向合并输出主表(左侧)不具有共同某特性的记录。
    select
    from students as s left outer join teachers as t on s.teacherid=t.tid where t.tid is null;
    右外连接:设右侧为主表,所有记录将全部输出,左为副表,两表进行横向合并,将左侧
    select from students as s right outer join teachers as t on s.teacherid=t.tid;
    右外连接特例:用where设置过滤条件,排除左右表具有某共同特性的记录,横向合并输出主表(右侧)不具有共同某特性的记录。
    select
    from students as s right outer join teachers as t on s.teacherid=t.tid where s.teacherid is null;
    完全外连接:两个表没有主副之分,两个表的记录全部输出,两表字段合并,左侧表某条记录右侧表没有值来填写时则对应字段为空,右侧表的记录左则表没有值来填充时则对应字段也为空,从而将两个表合并的同时也将两个表的记录全部输出,相当于两表互补全并,构成矩形。
    完全外连接特例:排除两表的交集,保留剩余部分,即交集取反

猜你喜欢

转载自blog.51cto.com/154773488/2455109