1、 select语句应用
1.1 select(单表)的执行逻辑
select 列1 , 列2
from 表
where 条件
group by 条件
having 条件
order by 条件
limit 条件
1.2 select单表查询
1> select单独使用的情况(MySQL独家)
(1)select @@参数名;
SELECT @@datadir; #查看数据存放的目录
wenjuan[(none)]>SELECT @@datadir;
+------------------+
| @@datadir |
+------------------+
| /data/3306/data/ |
+------------------+
1 row in set (0.00 sec)
wenjuan[(none)]>
SELECT @@port; #查看mysql的端口号
wenjuan[(none)]>SELECT @@port;
+--------+
| @@port |
+--------+
| 3306 |
+--------+
1 row in set (0.00 sec)
wenjuan[(none)]>
SELECT @@socket; #查看socket存放的目录
wenjuan[(none)]>SELECT @@socket;
+-----------------+
| @@socket |
+-----------------+
| /tmp/mysql.sock |
+-----------------+
1 row in set (0.00 sec)
wenjuan[(none)]>
SELECT @@innodb_flush_log_at_trx_commit;
wenjuan[(none)]>SELECT @@innodb_flush_log_at_trx_commit;
+----------------------------------+
| @@innodb_flush_log_at_trx_commit |
+----------------------------------+
| 1 |
+----------------------------------+
1 row in set (0.00 sec)
wenjuan[(none)]>
SHOW VARIABLES LIKE '%trx%';
wenjuan[(none)]>SHOW VARIABLES LIKE '%trx%';
+--------------------------------+-------+
| Variable_name | Value |
+--------------------------------+-------+
| innodb_api_trx_level | 0 |
| innodb_flush_log_at_trx_commit | 1 |
+--------------------------------+-------+
2 rows in set (0.00 sec)
wenjuan[(none)]>
SHOW VARIABLES; #513
(2)select 函数();
SELECT NOW(); 显示当前时间
wenjuan[(none)]>select now();
+---------------------+
| now() |
+---------------------+
| 2019-08-08 09:44:17 |
+---------------------+
1 row in set (0.00 sec)
wenjuan[(none)]>
SELECT DATABASE(); 当前在那个库中
wenjuan[(none)]>use world;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
wenjuan[world]>select database();
+------------+
| database() |
+------------+
| world |
+------------+
1 row in set (0.00 sec)
wenjuan[world]>
SELECT USER(); 当前登录的用户
wenjuan[world]>SELECT USER();
+----------------+
| USER() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)
wenjuan[world]>
SELECT MONTH(NOW()); 显示当前月份
wenjuan[world]>SELECT MONTH(NOW());
+--------------+
| MONTH(NOW()) |
+--------------+
| 8 |
+--------------+
1 row in set (0.00 sec)
wenjuan[world]>
SELECT CONCAT(USER,"@",HOST) FROM mysql.user;
SELECT CONCAT("hello") 单独使用没什么意思,要结合多列才能显示出效果
wenjuan[world]>SELECT CONCAT(USER,"@",HOST) FROM mysql.user;
+-------------------------+
| CONCAT(USER,"@",HOST) |
+-------------------------+
| root@10.0.0.% |
| wwj@10.0.0.% |
| wordpress@172.16.1.% |
| mysql.session@localhost |
| mysql.sys@localhost |
| root@localhost |
+-------------------------+
6 rows in set (0.00 sec)
wenjuan[world]>
SELECT GROUP_CONCAT(USER,"@",HOST) FROM mysql.user; 列转行
wenjuan[world]>SELECT GROUP_CONCAT(USER,"@",HOST) FROM mysql.user;
+------------------------------------------------------------------------------------------------------------+
| GROUP_CONCAT(USER,"@",HOST) |
+------------------------------------------------------------------------------------------------------------+
| root@10.0.0.%,wwj@10.0.0.%,wordpress@172.16.1.%,mysql.session@localhost,mysql.sys@localhost,root@localhost |
+------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
wenjuan[world]>
2> from子句使用
(1)SELECT * FROM city;
相当于Linux中的 cat /etc/passwd 等
(2)SELECT NAME,countrycode FROM city;
相当于Linux中的awk取列
3> where子句应用
(1)等值查询
##查询中国的城市信息?
wenjuan[world]>SELECT * FROM city WHERE CountryCode='CHN';
+------+---------------------+-------------+----------------+------------+
| ID | Name | CountryCode | District | Population |
+------+---------------------+-------------+----------------+------------+
| 1890 | Shanghai | CHN | Shanghai | 9696300 |
| 1891 | Peking | CHN | Peking | 7472000 |
| 1892 | Chongqing | CHN | Chongqing | 6351600 |
省略……
(2)不等值查询
一般用于数字列查询
##查询人口数量小于100人的城市?
wenjuan[world]>SELECT * FROM city WHERE population<100;
+------+-----------+-------------+----------+------------+
| ID | Name | CountryCode | District | Population |
+------+-----------+-------------+----------+------------+
| 2912 | Adamstown | PCN | – | 42 |
+------+-----------+-------------+----------+------------+
1 row in set (0.00 sec)
wenjuan[world]>
##查询id小于10的城市信息?
wenjuan[world]>SELECT * FROM city WHERE id<10;
+----+----------------+-------------+---------------+------------+
| ID | Name | CountryCode | District | Population |
+----+----------------+-------------+---------------+------------+
| 1 | Kabul | AFG | Kabol | 1780000 |
| 2 | Qandahar | AFG | Qandahar | 237500 |
| 3 | Herat | AFG | Herat | 186800 |
| 4 | Mazar-e-Sharif | AFG | Balkh | 127800 |
| 5 | Amsterdam | NLD | Noord-Holland | 731200 |
| 6 | Rotterdam | NLD | Zuid-Holland | 593321 |
| 7 | Haag | NLD | Zuid-Holland | 440900 |
| 8 | Utrecht | NLD | Utrecht | 234323 |
| 9 | Eindhoven | NLD | Noord-Brabant | 201843 |
+----+----------------+-------------+---------------+------------+
9 rows in set (0.00 sec)
wenjuan[world]>
##查询世界上不是中国的城市信息?
wenjuan[world]>SELECT * FROM city WHERE countryCode!='CHN';
+------+------------------------------------+-------------+------------------------+------------+
| ID | Name | CountryCode | District | Population |
+------+------------------------------------+-------------+------------------------+------------+
| 1 | Kabul | AFG | Kabol | 1780000 |
| 2 | Qandahar | AFG | Qandahar | 237500 |
| 3 | Herat | AFG | Herat | 186800 |
……
注意:尽量不使用不等于,可能不走索引,影响效率
(3)模糊查询
##查询国家代号为CH打头的城市信息?
wenjuan[world]>SELECT * FROM city WHERE countryCode LIKE 'CH%';
+------+---------------------+-------------+----------------+------------+
| ID | Name | CountryCode | District | Population |
+------+---------------------+-------------+----------------+------------+
| 3245 | Zürich | CHE | Zürich | 336800 |
| 3246 | Geneve | CHE | Geneve | 173500 |
| 3247 | Basel | CHE | Basel-Stadt | 166700 |
| 3248 | Bern | CHE | Bern | 122700 |
| 3249 | Lausanne | CHE | Vaud | 114500 |
| 554 | Santiago de Chile | CHL | Santiago | 4703954 |
| 555 | Puente Alto | CHL | Santiago | 386236 |
……
注意:避免使用like中前面带%的模糊查询
(4)逻辑连接符(and,or)
##查询中国城市人口超过500万的城市信息?
wenjuan[world]>SELECT * FROM city WHERE countryCode='CHN' AND population>5000000;
+------+-----------+-------------+-----------+------------+
| ID | Name | CountryCode | District | Population |
+------+-----------+-------------+-----------+------------+
| 1890 | Shanghai | CHN | Shanghai | 9696300 |
| 1891 | Peking | CHN | Peking | 7472000 |
| 1892 | Chongqing | CHN | Chongqing | 6351600 |
| 1893 | Tianjin | CHN | Tianjin | 5286800 |
+------+-----------+-------------+-----------+------------+
4 rows in set (0.00 sec)
wenjuan[world]>
##查看山东省或河北省的城市信息?
wenjuan[world]>SELECT * FROM city WHERE District='shandong' OR District='hebei';
+------+--------------+-------------+----------+------------+
| ID | Name | CountryCode | District | Population |
+------+--------------+-------------+----------+------------+
| 1903 | Qingdao | CHN | Shandong | 2596000 |
| 1904 | Jinan | CHN | Shandong | 2278100 |
| 1907 | Shijiazhuang | CHN | Hebei | 2041500 |
| 1921 | Zibo | CHN | Shandong | 1140000 |
| 1924 | Tangshan | CHN | Hebei | 1040000 |
| 1928 | Handan | CHN | Hebei | 840000 |
| 1948 | Zhangjiakou | CHN | Hebei | 530000 |
| 1955 | Baoding | CHN | Hebei | 483155 |
| 1960 | Yantai | CHN | Shandong | 452127 |
…………
##查询人口数量在500万到600万的城市?
wenjuan[world]>SELECT * FROM city WHERE population>5000000 AND population<6000000;
+------+----------------+-------------+----------------+------------+
| ID | Name | CountryCode | District | Population |
+------+----------------+-------------+----------------+------------+
| 207 | Rio de Janeiro | BRA | Rio de Janeiro | 5598953 |
| 1893 | Tianjin | CHN | Tianjin | 5286800 |
| 2298 | Kinshasa | COD | Kinshasa | 5064000 |
| 2823 | Lahore | PAK | Punjab | 5063499 |
+------+----------------+-------------+----------------+------------+
4 rows in set (0.00 sec)
wenjuan[world]>
(5)where配合between……and……使用
##查询人口数量在500万到600万的城市信息(包含500万到600万)?
wenjuan[world]>SELECT * FROM city WHERE population BETWEEN 5000000 AND 6000000;
+------+----------------+-------------+----------------+------------+
| ID | Name | CountryCode | District | Population |
+------+----------------+-------------+----------------+------------+
| 207 | Rio de Janeiro | BRA | Rio de Janeiro | 5598953 |
| 1893 | Tianjin | CHN | Tianjin | 5286800 |
| 2298 | Kinshasa | COD | Kinshasa | 5064000 |
| 2823 | Lahore | PAK | Punjab | 5063499 |
+------+----------------+-------------+----------------+------------+
4 rows in set (0.00 sec)
wenjuan[world]>
(6)where配合in使用
##查看山东省或河北省的城市信息?
SELECT * FROM city WHERE District IN ('shandong','hebei');
注意:in 对应相反的是 not in,但尽量不要使用,不走索引
4>group by分组子句+聚合函数应用
(1)什么是分组?
按照某个列进行分组
(2)常用的聚合函数
COUNT():计数
MAX():最大值
MIN():最小值
AVG():平均值
SUM():求和
GROUP_CONCAT():列转行
(3)实例:
##统计每个国家的城市个数?
wenjuan[world]>SELECT CountryCode,COUNT(id) FROM city GROUP BY CountryCode;
+-------------+-----------+
| CountryCode | COUNT(id) |
+-------------+-----------+
| ABW | 1 |
| AFG | 4 |
| AGO | 5 |
| AIA | 2 |
| ALB | 1 |
…………
##统计每个国家的总人口数?
wenjuan[world]>SELECT CountryCode,SUM(population) FROM city GROUP BY CountryCode;
+-------------+-----------------+
| CountryCode | SUM(population) |
+-------------+-----------------+
| ABW | 29034 |
| AFG | 2332100 |
| AGO | 2561600 |
| AIA | 1556 |
| ALB | 270000 |
| AND | 21189 |
…………
##统计中国每个省的城市个数及省总人口数?
wenjuan[world]>SELECT District,COUNT(NAME),SUM(population) FROM city WHERE countryCode='CHN' GROUP BY District;
+----------------+-------------+-----------------+
| District | COUNT(NAME) | SUM(population) |
+----------------+-------------+-----------------+
| Anhui | 16 | 5141136 |
| Chongqing | 1 | 6351600 |
| Fujian | 12 | 3575650 |
| Gansu | 7 | 2462631 |
| Guangdong | 20 | 9510263 |
| Guangxi | 9 | 2925142 |
| Guizhou | 6 | 2512087 |
| Hainan | 2 | 557120 |
…………
##统计各个国家的城市名列表?
wenjuan[world]>SELECT CountryCode,GROUP_CONCAT(NAME) FROM city GROUP BY CountryCode;
| CountryCode | GROUP_CONCAT(NAME) |
| ABW | Oranjestad | | AFG | Kabul,Qandahar,Herat,Mazar-e-Sharif |
| ARE | Dubai,Abu Dhabi,Sharja,al-Ayn,Ajman |
…………
5> having语句
##统计中国每个省的城市个数及省总人口数,只显示人口总数大于800万的省?
wenjuan[world]>SELECT District,COUNT(NAME),SUM(population) FROM city WHERE countryCode='CHN' GROUP BY District HAVING SUM(population)>8000000;
+--------------+-------------+-----------------+
| District | COUNT(NAME) | SUM(population) |
+--------------+-------------+-----------------+
| Guangdong | 20 | 9510263 |
| Heilongjiang | 21 | 11628057 |
| Hubei | 22 | 8547585 |
| Jiangsu | 25 | 9719860 |
| Liaoning | 21 | 15079174 |
| Shandong | 32 | 12114416 |
| Shanghai | 1 | 9696300 |
+--------------+-------------+-----------------+
7 rows in set (0.00 sec)
wenjuan[world]>
6> order b子句
##统计中国每个省的城市个数及省总人口数,只显示人口总数大于800万的省,并进行从大到小排序?
wenjuan[world]>SELECT District,COUNT(NAME),SUM(population) FROM city WHERE countryCode='CHN' GROUP BY District HAVING SUM(population)>8000000 ORDER BY SUM(population) DESC;
+--------------+-------------+-----------------+
| District | COUNT(NAME) | SUM(population) |
+--------------+-------------+-----------------+
| Liaoning | 21 | 15079174 |
| Shandong | 32 | 12114416 |
| Heilongjiang | 21 | 11628057 |
| Jiangsu | 25 | 9719860 |
| Shanghai | 1 | 9696300 |
| Guangdong | 20 | 9510263 |
| Hubei | 22 | 8547585 |
+--------------+-------------+-----------------+
7 rows in set (0.00 sec)
wenjuan[world]>
##查询中国所有城市信息,并以人口数降序输出?
wenjuan[world]>SELECT * FROM city WHERE District='shandong' UNION ALL SELECT * FROM city WHERE District='hebei';
+------+--------------+-------------+----------+------------+
| ID | Name | CountryCode | District | Population |
+------+--------------+-------------+----------+------------+
| 1903 | Qingdao | CHN | Shandong | 2596000 |
| 1904 | Jinan | CHN | Shandong | 2278100 |
| 1921 | Zibo | CHN | Shandong | 1140000 |
| 1960 | Yantai | CHN | Shandong | 452127 |
| 1963 | Weifang | CHN | Shandong | 428522 |
| 1977 | Zaozhuang | CHN | Shandong | 380846 |
| 1991 | Tai´an | CHN | Shandong | 350696 |
…………
7> limit应用
1> 语法:
LIMIT M offet N
LIMIT N,M
-- 跳过前N行,显示M行(N和M代表的是数字)
2> 实例:
##查询中国所有城市信息,并以人口数降序输出,并只取前五名?
wenjuan[world]>SELECT * FROM city WHERE countryCode='CHN' ORDER BY population DESC LIMIT 5;
+------+-----------+-------------+-----------+------------+
| ID | Name | CountryCode | District | Population |
+------+-----------+-------------+-----------+------------+
| 1890 | Shanghai | CHN | Shanghai | 9696300 |
| 1891 | Peking | CHN | Peking | 7472000 |
| 1892 | Chongqing | CHN | Chongqing | 6351600 |
| 1893 | Tianjin | CHN | Tianjin | 5286800 |
| 1894 | Wuhan | CHN | Hubei | 4344600 |
+------+-----------+-------------+-----------+------------+
5 rows in set (0.00 sec)
wenjuan[world]>
##查询中国所有城市信息,并以人口数降序输出,并只第6到10名?
SELECT * FROM city WHERE countryCode='CHN' ORDER BY population DESC LIMIT 5,5;
SELECT * FROM city WHERE countryCode='CHN' ORDER BY population DESC LIMIT 5 OFFSET 5;
8> distinct应用
##查询所有的国家代码信息
wenjuan[world]>SELECT DISTINCT countryCode FROM city;
+-------------+
| countryCode |
+-------------+
| ABW |
| AFG |
| AGO |
| AIA |
| ALB |
…………
9> union和union all的应用
查看山东省或河北省的城市信息?
wenjuan[world]>SELECT * FROM city WHERE District='shandong' UNION ALL SELECT * FROM city WHERE District='hebei';
+------+--------------+-------------+----------+------------+
| ID | Name | CountryCode | District | Population |
+------+--------------+-------------+----------+------------+
| 1903 | Qingdao | CHN | Shandong | 2596000 |
| 1904 | Jinan | CHN | Shandong | 2278100 |
| 1921 | Zibo | CHN | Shandong | 1140000 |
| 1960 | Yantai | CHN | Shandong | 452127 |
| 1963 | Weifang | CHN | Shandong | 428522 |
…………
| 1907 | Shijiazhuang | CHN | Hebei | 2041500 |
| 1924 | Tangshan | CHN | Hebei | 1040000 |
| 1928 | Handan | CHN | Hebei | 840000 |
| 1948 | Zhangjiakou | CHN | Hebei | 530000 |
…………
注意:他们的性能高于or 或 in 的性能
union和union all的区别?(面试题)
union带有去重复的功能,union all没有去重复的功能
1.3 select多表查询
1> 作用
业务需要的数据来自多张表时,会使用到多表查询
2> 多表连接类型
- 内连接 *****
- 外链接 ***
- 全连接 *
- 笛卡尔
3>多表连接的基本语法(内连接)
传统连接 where
自连接
join uing **
join on *****
4> join on 的语法
查询张三的家庭住址
SELECT A.name,B.address FROM
A JOIN B
ON A.id=B.id
WHERE A.name='zhangsan'
多表连接的套路:
- 根据需求找到关联表
- 找到表与标的关联列
- 列名调用时,需要添加表前缀
5> 别名的使用
(1)表别名
- 一般是在 FROM的表的别名,或者join后的表的别名
- 在 where, group by ,select后的列,having,order by
(2)列别名
- 一般是在select后的列,定义的别名
- 作用:
- 结果集显示会以别名形式展示
- 在hanving和order by 中可以调用列别名
6> 多表连接案例
(1)查询人口数量少于100人的城市所在:国家名,国土面积,城市名,人口数
USE world;
DESC city;
DESC country;
SELECT
country.name ,country.SurfaceArea,city.name,city.Population
FROM city
JOIN country
ON city.CountryCode=country.code
WHERE city.Population<100;
(2)统计zhang3学习了几门课程
SELECT student.sname ,COUNT(sc.sno) 课程数
FROM student
JOIN sc
ON student.sno=sc.sno
WHERE student.sname='li4';
(3)统计zhang3学习课程名称
SELECT student.sname ,GROUP_CONCAT(course.cname) 课程名称
FROM student
JOIN sc
ON student.sno=sc.sno
JOIN course
ON sc.cno=course.cno
WHERE student.sname='zhang3';
(4)oldguo老师教了学生的个数
SELECT th.tname,COUNT(st.sno) 个数 FROM teacher AS th
JOIN course AS cr ON th.tno=cr.tno
JOIN sc ON cr.cno=sc.cno
JOIN student AS st ON sc.sno=st.sno
WHERE tname='oldguo';
(5)每位老师所教课程的平均分,并按平均分排序
SELECT th.`tname` tname,cr.`cname` cname,cr.`cno` cno,AVG(sc.`score`) avg_score FROM teacher AS th
JOIN course AS cr ON th.tno=cr.tno
JOIN sc ON cr.cno=sc.cno
GROUP BY th.`tname`,cr.`cname`
ORDER BY avg_score DESC
(6)查询oldguo所教的不及格的学生姓名
SELECT th.`tname`,st.`sname`,sc.`score` FROM teacher AS th
JOIN course AS cr ON th.tno=cr.tno
JOIN sc ON cr.cno=sc.cno
JOIN student AS st ON sc.sno=st.sno
WHERE score<60 AND tname='oldguo';
(7)查询所有老师所教学生不及格的信息
SELECT th.tname 教师名称,GROUP_CONCAT(st.sname) 不及格的学生 FROM teacher AS th
INNER JOIN course AS cr ON th.tno=cr.tno
INNER JOIN sc ON cr.cno=sc.cno
INNER JOIN student AS st ON sc.sno=st.sno
WHERE score<60
GROUP BY th.tname