MySQL-SQL基础应用(DQL基础应用--单表及多表查询)

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)   |
+-------------------------+
| [email protected].%           |
| [email protected].%            |
| [email protected].%    |
| 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)                                                                                |
+------------------------------------------------------------------------------------------------------------+
| [email protected].%,[email protected].%,[email protected].%,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

你可能感兴趣的:(MySQL-SQL基础应用(DQL基础应用--单表及多表查询))