SQL查询基础

1、单表查询

从数据库中查找数据 专业的称谓又称为投影

基本查询语句结构

select from

* 所有列不是所有其他东西

查询所有数据

例:SELECT * FROM t_studen

需要执行比较细的操作  加上条件筛选:查询id2号的学生信息

SELECT * FROM t_student WHERE id=2;

筛选的执行步骤  

例:SELECT * FROM t_student WHERE id=2;

SELECT *          (3) 再查询  筛选完后 我最终投影的结果就是筛选后的结果,不是每行都显示出来,显示行的数据是筛选后的数据  所以最后执行 select

FROM t_student    (1) 把整张表加到内存里面  把整张表找到后加到内存里面

WHERE id =2      (2) 筛选  因为一张表里面的数据需要去做一个筛选,不想让每行都显示,这样就没意义了,所以要进行一个条件筛选

只投影某些列

SELECT id,s_name FROM t_student;  只投影结果,而不是改变表数据,很多人会迷惑,其他列会不会不见了

查询出来显示成中文,比如s_name显示成学生姓名

 

 

 AS 加上别名  (列的别名)

SELECT id,s_name AS "学生姓名"  FROM t_student;

表别名,当有几张表的时候,表的名字很长,会给表加上别名

SELECT t_student.s_name FROM t_student  -- 但是在一张表中这样写t_student.s_name 没有任何意义

SELECT a.s_name FROM t_student a  本次查询 a就代表t_student 就可以a.s_name

 

 

1.1筛选掉重复数据 DISTINCT

SELECT DISTINCT s_name FROM t_student;

SELECT DISTINCT s_name,s_classid FROM t_student;   distinct 要重复列(s_name,s_classid)的数据完全一样

 

1.2选择操作:写筛选条件的方法:

 

并且  and 也可以写成&&

SELECT * FROM t_student WHERE id=2 AND s_name='李四' AND s_classid='二班'

SELECT * FROM t_student WHERE id=2 AND s_name='李四' && s_classid='二班'

 

或者 or 也可以写成 ||

SELECT * FROM t_student WHERE s_classid='二班' OR id=1

SELECT * FROM t_student WHERE s_classid='二班' || id=1

 

范围操作BETWEEN……AND……包含

语法:select 列 from 表名 where 列名 between 值  and 值;

SELECT * FROM t_student WHERE age>=18 AND age<=25

SELECT * FROM t_student WHERE age BETWEEN 18 AND 25  -- 等同于上面大于等于 及小于等于

小于等于18和一班,大于等于25和一班

SELECT * FROM t_student WHERE age<=18  OR age>=25 AND s_classid='一班';

这条语句执行出来的结果是小于等于18的所有数据和大于等于25并且是一班的数据

是因为and的优先级高于or的优先级

所以应该这样写:

SELECT * FROM t_student WHERE (age<=18  OR age>=25 ) AND s_classid='一班';

小于等于18和一班,大于等于25和一班   and优先级高于or 所以一般是单独用括号括起来

查询学生年纪为18 或者25 或者28

SELECT * FROM t_student WHERE age=18 OR age=25 OR age=28

 

in 操作  

简化上面的那种情况  where in(1,值2,值3)

SELECT * FROM t_student WHERE age IN(18,25,30)

 

not in 操作

值不是25

SELECT * FROM t_student WHERE age NOT IN(25)

 

返回限定行数 limit

limit 数字=从第一行数据开始 数两行

limit 数字n,数字m    从第n行数据开始(跟数组下标计算方式一样) m行  跟字符串substr类似

SELECT * FROM t_student LIMIT 2

SELECT * FROM t_student LIMIT 2,2

返回第二行之后所有行  第二个参数足够大  超出也只会返回到最后一行为止  

SELECT * FROM t_student LIMIT 2,100  

返回多少行   应用场景?  一些网站数据较多时,要出现分页

 

1.3模糊查询 

 

% 不限制字符

语法:select * from 表名 where 字段 like x%;

找所有姓张的学生

SELECT * FROM t_student WHERE s_name='张三'      = 全匹配 不会帮你自动模糊查询

SELECT * FROM t_student WHERE s_name LIKE '张%'  like % 不限制字符(0-N个字符)的模糊查询

SELECT * FROM t_student WHERE s_name LIKE '%张%'  like % 可以查到包含张  **

SELECT * FROM t_student WHERE s_name LIKE '%张  like % 可以查到张,以张结尾, 但是不能是张**

 

占位符 _(下划线)   一个下划线代表一个字符

找所有姓张的学生,并且名字长度为三个字

SELECT * FROM t_student WHERE s_name LIKE '张__'    like _ 限制字符数的模糊查询  一个下划线代表一个字符

查询年纪为空的学生信息

SELECT * FROM t_student WHERE age=""        ''”代表为空白的值

 

空值 is null

SELECT * FROM t_student WHERE age IS NULL    代表空值  没有输入数据

 

不是空 is not null

SELECT * FROM t_student WHERE age IS NOT NULL

上面的操作 投影出来的东西 跟我们的表数据(输入顺序)中是一样的顺序,比如想让它以

 

排序   order by           升序 ASC 降序 desc

年龄大小排序

SELECT * FROM t_student ORDER BY age  -- 默认是升序

SELECT * FROM t_student ORDER BY age DESC  -- 降序

SELECT * FROM t_student ORDER BY age ASC  -- 升序

多于一个条件的排序

SELECT * FROM t_student ORDER BY age ASC,id ASC     会先让age排序,

然后如果age有两个一样,再让id排序age的顺序,一般不会全部考虑,只有当两条数据一样,才考虑第二个条件

 

1.4、聚合函数

 

计数 count()

语法:select count() as ‘总数’ from 表名 where 条件  -------一般在计数的时候都会给取个别名

Count 统计时不包含没有值的项

计算年龄在20岁的人数

例:SELECT COUNT(*) FROM t_student  WHERE age=20

 

求和 sum()

语法:select sum() from 表名

例:SELECT SUM(age) FROM t_student

 

平均 avg

语法:1select sun()/count(*) from 表名

例:SELECT SUM(age)/COUNT(*) FROM t_student

(2)select avg() from 表名     -------默认不包含空

例:SELECT AVG(age) FROM t_student

(3)Select avg(ifnull(,0)) from 表名   -----如果是空数据,补成0在求平均

:SELECT AVG(IFNULL(age,0)) FROM t_student

 

最大值、最小值

语法:select max(),min() from 表名

例:SELECT MAX(age),MIN(age) FROM t_student

 

分组 group by

语法:select 列名 ,count(*) from 表名 group by 需要分组的列名   (必须和前面的列相关联)

select 列名 ,count(*) from 表名 group by 需要分组的列名 having 条件

例:查询每一班的人数

SELECT s_classid,COUNT(*) FROM t_student GROUP BY s_classid;

显示10岁(where)的人数大于2的班级的一条数据

SELECT s_classid,COUNT(*) FROM t_student WHERE age=10 GROUP BY s_classid HAVING(COUNT(*)>2);

执行步骤:

SELECT s_classid,COUNT(*)       -- 4 投影

FROM t_student                           -- 1 把表加载到内存

WHERE age=10                            -- 2 筛选  

GROUP BY s_classid                    -- 3分组

HAVING(COUNT(*)>2)                   -- 5 二次筛选,首先要得到第一次的结果 才可以进行筛选

                                                     -- havingwhere都是筛选条件,where是分组前,因为分组前没有执行聚合函数

                                                     -- having是在分组后,只能用做聚合函数的过滤

 

显示10岁(where)的人数大于1的班级并且按照人数排序

SELECT s_classid,COUNT(*) FROM t_student WHERE age=10 GROUP BY s_classid HAVING(COUNT(*)>=1) ORDER BY COUNT(*)  limit 1

执行步骤:

SELECT s_classid,COUNT(*)       -- 4 投影

FROM t_student                           -- 1 把表加载到内存

WHERE age=10                            -- 2 筛选  

GROUP BY s_classid                    -- 3 分组

HAVING(COUNT(*)>=1)                 -- 5 二次筛选 首先要得到第一次的结果 才可以进行筛选

ORDER BY COUNT(*) DESC        -- 6 二次分组

LIMIT 1                                         -- 7 限定行数 肯定是你执行完之后最终的结果的 行数   

                                                    -- 7步顺序千万不能搞错

 

2、多表查询

 

2.1、相关子查询

子查询必须依赖于主查询 ,子查询单独运行会报错,依赖于主查询的结果

 

select嵌套  只能返回单行单列

每次主查询 执行一次,子查询也会执行一次,最终执行N+1次,效率低下,如果主查询没有提供数据,子查询无法执行

语法:select 列名1,列名2,(select 列名 from 表名 where 条件) from 表名

例:SELECT s_name,(SELECT c_name FROM t_class WHERE c_id=s_classid) FROM t_student

 

2.2 非相关子查询

from 嵌套   必须要给嵌套的子查询表起别名,可返回多行多列数据

子查询对主查询没有依赖  子查询只会执行一次,只会在from的时候才执行,性能较高,能独立运行,只是给主查询提供条件值

语法:select 列名1 ,列名2,.... from (select 列名 from 表名 [where 条件] )  [where 条件]

例:查询性别为女 并且姓名为张三的

SELECT * FROM (SELECT * FROM t_student WHERE s_sex='') AS t1

WHERE t1.s_name='张三';

 

where 嵌套  执行2次,子查询可以单独运行,不依赖主查询,只是给主查询提供条件值

语法:select 列名1,列名2, .... from 表名 where 列名 关系运算符 (select 列明 from 表名 where 条件)

例:查询一班的学生有哪些

SELECT * FROM t_student WHERE s_classid=(SELECT c_id FROM t_class WHERE c_name='一班')

 

in 多条值

例:查询一班的学生有哪些

语法:select 列名1,列名2,.... from 表名 where 列名 in (select 列明 from 表名 where 条件)

SELECT * FROM t_student WHERE s_classid in (SELECT c_id FROM t_class WHERE c_name='一班')

any all 必须跟子查询 不能单独使用

 

all 任意值

语法:select 列名1,列名2, .... from 表名 where 列名 关系运算符 all (select 列明 from 表名 where 条件)

例:查询分数高于任意一个张三的所有学生  -- 使用all

SELECT * FROM t_student WHERE s_score>ALL(SELECT s_score FROM t_student WHERE s_name='张三')

 

any

语法:select 列名1,列名2, .... from 表名 where 列名 关系运算符 any (select 列明 from 表名 where 条件)

例:查询分数高于任意一个张三的所有学生

SELECT * FROM t_student WHERE s_score>ANY( SELECT s_score FROM t_student WHERE s_name='张三');

还可以使用MIN

SELECT * FROM t_student WHERE s_score>(SELECT MIN(s_score) FROM t_student WHERE s_name='张三');

子查询不管怎么变,都只有三种,在where中嵌套一个,form 一个,select一个

posted on 2017-09-20 17:50  hongyeye  阅读(9012)  评论(0编辑  收藏  举报