1-MySQL -单表查询
before
准备数据:
select单独使用
select @@xxx
select语句单独使用一般是搭配@@
语句查询一些系统信息之类的:
SELECT @@port;
SELECT @@version;
SELECT @@basedir;
SELECT @@datadir;
SELECT @@server_id;
@@
后必须跟参数的全名,当然对于一些特别长的,你可能记不住:
SELECT @@innodb_flush_log_at_trx_commit;
SHOW VARIABLES LIKE 'innodb_flush%';
太长了记不住,可以使用SHOW
语句进行模糊匹配查询。
select调用函数
select语句也可以直接调用函数:
SELECT NOW();
SELECT DATABASE(); -- 当前所在数据库
SELECT USER();
SELECT CONCAT("hello world"); -- 拼接字符串,如下是拼接的用法,了解即可
-- SELECT USER,HOST FROM mysql.user;
-- SELECT CONCAT(USER,"@",HOST) FROM mysql.user;
-- SELECT GROUP_CONCAT(USER,"@",HOST) FROM mysql.user;
-- SELECT CONCAT_WS('@', USER,HOST) FROM mysql.user;
更多内置函数参考:SQL Function and Operator Reference
from
from的两种常用方式:
SELECT col1,col2 FROM 表; -- 查询指定列
SELECT * FROM 表; -- 全表查询,不要在生产中使用,性能太差
一般在生产中,select语句不加where语句是不允许通过的。
在查询中也可以使用四则运算:
SELECT population*20,population FROM city;
where
where是过滤的意思,可以加各种过滤条件,基本语法:
SELECT col1,col2 FROM TABLE WHERE col 条件;
来看常用的用法。
where配合等值查询
等值查询也就是col=xx
的操作:
-- 查询中国(CHN)所有城市信息
SELECT * FROM city WHERE countrycode='CHN';
-- 查询中国郑州市信息
SELECT * FROM city WHERE NAME='zhengzhou';
-- 查询中国河南省所有城市信息
SELECT * FROM city WHERE district='henan';
where配合比较操作符
比较运算符也就是>、>=、<、<=、!=(<>)
这些操作了:
-- 查询世界上人口小于十万人的城市
SELECT * FROM city WHERE population<100000;
-- 查询世界上人口大于一千万人的城市
SELECT * FROM city WHERE population>10000000;
-- 不等于这里,用 <> 和 != 都可以
SELECT * FROM city WHERE countrycode='CHN' AND DISTRICT!='shanghai';
SELECT * FROM city WHERE countrycode='CHN' AND DISTRICT<>'shanghai';
where配合逻辑运算符
逻辑运算符这里常用的有and or
,not
用的少,这里就不说了:
-- 查询中国人口数大于800万的城市
SELECT * FROM city WHERE countrycode='CHN' AND population>8000000;
-- 查询中国或美国城市信息
SELECT * FROM city WHERE countrycode='CHN' OR countrycode='USA';
where配合模糊查询
-- 查询中国以"hu"开头省的城市信息
SELECT * FROM city WHERE district LIKE 'hu%';
like
查询中,支持下面两种符号:
%
,任意长度字符,注意,条件左边不能使用%
,因为这样查询时不走索引(索引遵循最左原则)。_
,任意一个字符。
where配合in语句
-- 查询中国或美国城市信息
SELECT * FROM city WHERE countrycode='CHN' OR countrycode='USA';
SELECT * FROM city WHERE countrycode IN ('CHN', 'USA');
上面两条语句是等价的,性能也是一样的,虽然性能都不怎么样!
where配合between and
语句
-- 查询世界上人口数量在100万-200万之间的城市
SELECT * FROM city WHERE population<=2000000 AND population>=1000000;
SELECT * FROM city WHERE population BETWEEN 1000000 AND 2000000;
where配合is语句
判断一个字段是否为空不用等号,而是使用is
语句:
-- 返回city表中countrycode是CHN的,并且district字段不为空的前10条数据
SELECT * FROM city WHERE countrycode='CHN' AND district IS NOT NULL LIMIT 10;
group by+聚合函数
根据by
后面的(一个或多个)条件进行分组,便于统计。
常用聚合(统计)函数
max()
:最大值。min()
:最小值。avg()
:平均值。sum()
:总和。count()
:个数。
另外再加一个函数:
group_concat()
:列转行。
示例:
-- 统计世界上每个国家的总人口数量
SELECT countrycode,SUM(population) FROM city GROUP BY countrycode;
-- 统计中国每个省的总人口数量
SELECT district,SUM(population) FROM city WHERE countrycode='CHN' GROUP BY district;
-- 统计世界上每个国家的城市数量
SELECT countrycode,COUNT(NAME) FROM city GROUP BY countrycode;
SELECT countrycode,COUNT(id) FROM city GROUP BY countrycode;
-- 统计中国每个省的城市列表
SELECT district,GROUP_CONCAT(NAME) FROM city WHERE countrycode='CHN' GROUP BY district;
-- 统计中国每个省的平均人口
SELECT district,AVG(population) FROM city WHERE countrycode='CHN' GROUP BY district;
在MySQL的SQL执行逻辑中,where条件必须放在group by前面!也就是先通过where条件将结果查询出来,再交给group by去分组,完事之后进行统计。
除此之外,如果使用unique字段作为分组依据,这样的话每条记录都自成一组,这么做是没有意义的。
having
-- 统计中国每个省的总人数,只打印人口数量小于50万的省份
SELECT district,SUM(population)
FROM city
WHERE countrycode='CHN'
GROUP BY district
HAVING SUM(population)<500000;
注意,having子句是后过滤语句,在group by后面再进行过滤,并且having子句不走索引,针对这个问题,我们一般采用临时表来解决。
order by + limit
order by
通常和limit搭配使用。
order by
在having语句后面执行。
学到这里,我们也能发现,MySQL中的SQL语句的执行顺序:
SELECT FROM WHERE GROUP BY HAVING ORDER BY LIMIT
示例:
-- 查询中国的城市信息,并且按照人口数量降序排序
SELECT * FROM city WHERE countrycode='CHN' ORDER BY population DESC;
-- 查询美国的城市信息,并且按照人口数量升序排序
SELECT * FROM city WHERE countrycode='USA' ORDER BY population ASC;
-- 统计中国每个省的总人口,找出大于500万的,并按照人口数量降序排序
SELECT district,SUM(population)
FROM city
WHERE countrycode='CHN'
GROUP BY district
HAVING SUM(population)>5000000
ORDER BY SUM(population) DESC;
-- 统计中国每个省的总人口,找出大于500万的,并按照人口数量降序排序,只打印前3条结果
SELECT district,SUM(population)
FROM city
WHERE countrycode='CHN'
GROUP BY district
HAVING SUM(population)>5000000
ORDER BY SUM(population) DESC
LIMIT 3;
MySQL中默认排序是升序ASC
;降序是DESC
,还有一种情况是,比如说按照年龄排序,但是有的年龄是相同的,该怎么排序,这里我们可以这样处理:
-- 根据age升序排序,如果age相同,这按照id降序排序
SELECT * FROM employee ORDER BY age,id desc;
下来来解释LIMIT
语句为什么通常和ORDER BY
一起使用,因为有序的或经过筛选的数据更有意义,无序的数据使用LIMIT
在实际生产中意义不大;
再来说说LIMIT
的常用用法:
LIMIT N -- 返回前N行
LIMIT N,M -- 跳过前N行,返回M行,如LIMIT 5,5,意思是跳过前5行,从第6行开始显式5条
-- 上下两个用法相反,推荐使用上面的
LIMIT M OFFSET N -- 显式M行,跳过N行,如LIMIT 5,3,意思是跳过前3行,从第4行开始,显式5行
正则表达式查询
-- 查询中国重庆
SELECT * FROM city WHERE countrycode='CHN' AND district REGEXP '^C.*g$';
distinct
distinct去重,来看示例:
-- 查询世界上所有国家码
SELECT countrycode FROM city; -- 返回结果有重复
SELECT DISTINCT(countrycode) FROM city; -- DISTINCT 去重
联合查询-union
联合查询的意思就是将两个同类型的结果集合并成一个,比如:
-- 查询中国和美国的城市信息
SELECT countrycode,NAME FROM city WHERE countrycode IN ('CHN','USA');
示例的意思是将查询到的中国城市信息的结果加上美国的城市信息加一起再返回,除了上述使用 IN
语句来完成也可以使用联合查询来完成,这里也更推荐使用联合查询:
-- 查询中国和美国的城市信息
SELECT countrycode,NAME FROM city WHERE countrycode='CHN'
UNION ALL
SELECT countrycode,NAME FROM city WHERE countrycode='USA';
上述UNION ALL
就是拼接了两个同类型的结果,当然,你还可以继续拼接:
-- 查询中国(CHN)、美国(USA)、日本(JPN)、英国(GBR)的城市信息
SELECT countrycode,NAME FROM city WHERE countrycode='CHN'
UNION ALL
SELECT countrycode,NAME FROM city WHERE countrycode='USA'
UNION ALL
SELECT countrycode,NAME FROM city WHERE countrycode='JPN'
UNION ALL
SELECT countrycode,NAME FROM city WHERE countrycode='GBR';
注意,UNION ALL
的性能高于IN
、OR
语句;所以,如果可以的话,我们尽量使用UNION ALL
语句来代替IN
、OR
语句。
另外,在MySQL中,不是SQL语句越短性能越高!
最后,再来补充一下,联合查询有两种写法:
- union:对两个结果集进行并集操作,不包括重复行,也就是带有去重功能,同时进行默认规则的排序,另外,带有去重就意味着有性能上的消耗。
- union All:对两个结果集进行并集操作,包括重复行,也就是不去重,同时也不进行排序;
以上就是单表查询中常用的语句用法了。
that's all,see also: