sql
sql子句
from 指定表
where 满足条件
group by 将查出来的记录分组
into 创建新表,将查询出来的插入新表
having 指定分组条件
order by 指定排序条件
union 将两个或者多个查询结果组合
compute 生成合计,作为附加列出现在结果集的最后
COUNT(column) 统计column非NULL的行数.
** sql查询已一行为单位,select后面跟着的可以
select name,round(5000,5) population,round(5222,2) from world
select name, population,area from world where (area>3000000 and population<250000000) or (area < 3000000 and population>250000000)
SELECT title FROM movies where director = 'John Lasseter' order by Length_minutes desc limit 1 offset 2;//取一条,从第三条开始截
SELECT * FROM movies order by director asc,year desc limit 10;//按照导演名字排序,排序完后再按照年份排序
结论:IN()适合B表比A表数据小的情况
结论:EXISTS()适合B表比A表数据大的情况
inner join
SELECT director,International_sales FROM movies inner join Boxoffice on movies.id = Boxoffice.movie_id //构建了一个新表,左边表匹配右边表
order by International_sales desc limit 1 //操作新结合表
LEFT JOIN
保留A的所有行,不管有没有能匹配上B 反过来
RIGHT JOIN
则保留所有B里的行。
FULL JOIN
不管有没有匹配上
INNER JOIN
是两个集合的交集。
SELECT DISTINCT buildings.building_name, employees.Role FROM buildings left join employees on buildings.building_name = employees.building
Distinct 后面可以跟多个列的不重复
在 GROUP BY
分组语法中,我们知道数据库是先对数据做WHERE
,然后对结果做分组
group by是在查询时先把纪录按照类别分出来再查询。
group by 必须在查询结果中包含一个聚集函数,而distinct不用
HAVING
语法将用来解决这个问题,他可以对分组之后的数据再做SELECT筛选.
查询执行顺序
1. FROM
和 JOIN
s
FROM
或 JOIN
会第一个执行,确定一个整体的数据范围. 如果要JOIN不同表,可能会生成一个临时Table来用于 下面的过程。总之第一步可以简单理解为确定一个数据源表(含临时表)
2. WHERE
我们确定了数据来源 WHERE
语句就将在这个数据源中按要求进行数据筛选,并丢弃不符合要求的数据行,所有的筛选col属性 只能来自FROM
圈定的表. AS别名还不能在这个阶段使用,因为可能别名是一个还没执行的表达式
3. GROUP BY
如果你用了 GROUP BY
分组,那GROUP BY
将对之前的数据进行分组,统计等,并将是结果集缩小为分组数.这意味着 其他的数据在分组后丢弃.
4. HAVING
如果你用了 GROUP BY
分组, HAVING
会在分组完成后对结果集再次筛选。AS别名也不能在这个阶段使用.
5. SELECT
确定结果之后,SELECT
用来对结果col简单筛选或计算,决定输出什么数据.
6. DISTINCT
如果数据行有重复DISTINCT
将负责排重.
7. ORDER BY
在结果集确定的情况下,ORDER BY
对结果做排序。因为SELECT
中的表达式已经执行完了。此时可以用AS别名.
8. LIMIT
/ OFFSET
最后 LIMIT
和 OFFSET
从排序的结果中截取部分数据.
--请输入sql
select Director,sum(Domestic_sales+International_sales) from Movies inner join Boxoffice on Movies.id =Boxoffice.Movie_id
group by director;
select * from Student RIGHT JOIN (
select t1.sid from (
(select sid ,score as class1 from SC where SC.CId = '01') as t1
,(select sid ,score as class2 from SC where SC.CId = '02') as t2
)
where t1.sid = t2.sid and t1.class1>t2.class2
) as r
on Student.SId = r.sid
--简单Case函数
CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE '其他' END
行转列,列转行
行转列,通过union查询记录,将记录连接在一张表里
SELECT userid,cn_score from tb_score1
union
select userid,math_score from tb_score1
;
首先分组,再通过user_id,聚合函数sum或者max,拼出一个列
SELECT userid,
SUM(IF(`subject`='语文',score,0)) as '语文',
SUM(IF(`subject`='数学',score,0)) as '数学',
SUM(IF(`subject`='英语',score,0)) as '英语',
SUM(IF(`subject`='政治',score,0)) as '政治'
FROM tb_score
GROUP BY userid
SUM() 是为了能够使用GROUP BY根据userid进行分组,因为每一个userid对应的subject="语文"的记录只有一条,所以SUM() 的值就等于对应那一条记录的score的值
一个user对应一个subject只有一个分数
select * from table_a where a.id = x;
select * from table_a where a.id = y;
select * from table_a where a.id = z;
select * from table_a where a.id in x,y,z
查询条件为多个的时候可以使用in查询,上面的sql查询结果是一样的,只不过“=” 的sql,与数据库产生的连接会多两条。查询效率低下最主要的原因是与数据库产生的连接过多,数据库查询的速度其实很快,但是建立连接,断开连接速度相对于查询就偏慢了。
当查询两张表的交集的时候
我以前的做法是查询两张表的数据,将它们的外键id相减,就可以查询出交集的部分。
另外还有更好的做法是 sql的内外连接,左右连接
但是在进行多表连接时,会生成一张临时表返回给用户
这张临时表包含两张表所有的数据
在进行连接查询的时候,写条件时是用where呢还是用on呢?
- where
对生成的临时表进行过滤,不符合的就直接过滤掉
是对临时表记录的筛选
最后根据条件返回的记录可能只有一条
±-----±-----±--------+
| id | name | local |
±-----±-----±--------+
| 1 | a11 | beijing |
±-----±-----±--------+ - on
对右表进行数据过滤,会返回左表的所有行,右表中不存在的就补为null
是对右表的匹配筛选
最后返回左表的所有数据与右表中符合条件的数据,不符合条件的右表数据显示为null
±-----±-----±--------+
| id | name | local |
±-----±-----±--------+
| 1 | a11 | beijing |
| 2 | a22 | NULL |
| 3 | a33 | NULL |
| 4 | a44 | NULL |
内链接:
说明:连接两张表,返回符合查询条件的记录(也就是两张表的交集部分)
select * from table_a a inner join table_b b where a.id = b.id;
select * from table_a a inner join table_b b on a.id = b.id;
左右连接
说明:返回左表全数据,然后根据条件匹配返回右表中符合条件的数据,不符合就为null
select * from table_a a left join table_b b where a.id = b.id;
select * from table_a a right join table_b b on a.id = b.id;