1. 基本查询
查询基本使用包括:条件、排序、聚合函数、分组和分页。
实例详解查询
1> 创建students表用作实验
MariaDB [testdb]> drop table students; #删除上节创建的表 MariaDB [testdb]> create table students ( #创建students表 -> id int unsigned not null auto_increment primary key, -> name varchar(20) default '', -> age tinyint unsigned default 0, -> high decimal(5,2), -> gender enum('男', '女', '中性', '保密') default '保密', -> cls_id int unsigned default 0, -> is_delete bit default 0 -> ); MariaDB [testdb]> show table students; #给表里面写入数据 ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'students' at line 1 MariaDB [testdb]> insert into students values -> (0,'小明',18,180.00,1,1,0), -> (0,'小月月',19,180.00,1,2,0), -> (0,'彭于晏',28,185.00,1,1,0), -> (0,'刘德华',58,175.00,1,2,0), -> (0,'黄蓉',108,160.00,2,1,0), -> (0,'凤姐',44,150.00,4,2,1), -> (0,'王祖贤',52,170.00,2,1,1), -> (0,'周杰伦儿',34,null,1,1,0), -> (0,'程坤',44,181.00,1,2,0), -> (0,'和珅',55,166.00,1,2,0), -> (0,'刘亦菲',29,162.00,2,3,0), -> (0,'金星',45,180.00,3,4,0), -> (0,'静香',18,170.00,2,4,0), -> (0,'郭靖',22,167.00,1,5,0), -> (0,'周杰',33,178.00,1,1,0), -> (0,'钱小豪',56,178.00,1,1,0), -> (0,'谢霆锋',38,175.00,1,1,0), -> (0,'陈冠希',38,175.00,1,1,0);
2> 查询
查询所有列(字段)
格式: select * from 表名
MariaDB [testdb]> select * from students; +----+---------------+-- ---+-------+----------+--------+---------+ | id | name | age | high | gender | cls_id |is_delete | +----+--------------+----- -+--------+--------+--------+----------+ | 1 | 小明 | 18 | 180.00 | 男 | 1 | | | 2 | 小月月 | 19 | 180.00 | 男 | 2 | | | 3 | 彭于晏 | 28 | 185.00 | 男 | 1 | | | 4 | 刘德华 | 58 | 175.00 | 男 | 2 | | | 5 | 黄蓉 | 108 | 160.00 | 女 | 1 | | | 6 | 凤姐 | 44 | 150.00 | 保密 | 2 | | | 7 | 王祖贤 | 52 | 170.00 | 女 | 1 | | | 8 | 周杰伦儿 | 34 | NULL | 男 | 1 | | | 9 | 程坤 | 44 | 181.00 | 男 | 2 | | | 10 | 和珅 | 55 | 166.00 | 男 | 2 | | | 11 | 刘亦菲 | 29 | 162.00 | 女 | 3 | | | 12 | 金星 | 45 | 180.00 | 中性 | 4 | | | 13 | 静香 | 18 | 170.00 | 女 | 4 | | | 14 | 郭靖 | 22 | 167.00 | 男 | 5 | | | 15 | 周杰 | 33 | 178.00 | 男 | 1 | | | 16 | 钱小豪 | 56 | 178.00 | 男 | 1 | | | 17 | 谢霆锋 | 38 | 175.00 | 男 | 1 | | | 18 | 陈冠希 | 38 | 175.00 | 男 | 1 | | +----+---------- --+------+--------+--------+-------+------------+ 18 rows in set (0.001 sec)
一定条件查询:
用条件语句where,后面跟条件。
MariaDB [testdb]> select * from students where id>5; #支持条件表达式、逻辑语言and、&&、or、|| +----+-----------+------+--------+--------+---------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+-----------+------+--------+--------+---------+-----------+ | 6 | 凤姐 | 44 | 150.00 | 保密 | 2 | | | 7 | 王祖贤 | 52 | 170.00 | 女 | 1 | | | 8 | 周杰伦儿 | 34 | NULL | 男 | 1 | | | 9 | 程坤 | 44 | 181.00 | 男 | 2 | | | 10 | 和珅 | 55 | 166.00 | 男 | 2 | | | 11 | 刘亦菲 | 29 | 162.00 | 女 | 3 | | | 12 | 金星 | 45 | 180.00 | 中性 | 4 | | | 13 | 静香 | 18 | 170.00 | 女 | 4 | | | 14 | 郭靖 | 22 | 167.00 | 男 | 5 | | | 15 | 周杰 | 33 | 178.00 | 男 | 1 | | | 16 | 钱小豪 | 56 | 178.00 | 男 | 1 | | | 17 | 谢霆锋 | 38 | 175.00 | 男 | 1 | | | 18 | 陈冠希 | 38 | 175.00 | 男 | 1 | | +----+----------+------+---------+--------+---------+-----------+
select * from语句虽然简单,但对于企业来说,数据量特别大,使用该命令会列出所有的数据,严重影响内存。一般不直接用该命令。
3> 查看指定列
MariaDB [testdb]> select id,name from students; +----+--------------+ | id | name | +----+--------------+ | 1 | 小明 | | 2 | 小月月 | | 3 | 彭于晏 | | 4 | 刘德华 | | 5 | 黄蓉 | | 6 | 凤姐 | | 7 | 王祖贤 | | 8 | 周杰伦儿 | | 9 | 程坤 | | 10 | 和珅 | | 11 | 刘亦菲 | | 12 | 金星 | | 13 | 静香 | | 14 | 郭靖 | | 15 | 周杰 | | 16 | 钱小豪 | | 17 | 谢霆锋 | | 18 | 陈冠希 | +----+--------------+
4>通过表名查询
大量含有相同字段的不同类型的表查询时容易混淆,因此加表名进行查询得到的结果比较合理。
MariaDB [testdb]> select students.id,students.name from students; +----+--------------+ | id | name | +----+--------------+ | 1 | 小明 | | 2 | 小月月 | | 3 | 彭于晏 | | 4 | 刘德华 | | 5 | 黄蓉 | | 6 | 凤姐 | | 7 | 王祖贤 | | 8 | 周杰伦儿 | | 9 | 程坤 | | 10 | 和珅 | | 11 | 刘亦菲 | | 12 | 金星 | | 13 | 静香 | | 14 | 郭靖 | | 15 | 周杰 | | 16 | 钱小豪 | | 17 | 谢霆锋 | | 18 | 陈冠希 |
5> 给表起别名查询
使用as
MariaDB [testdb]> select s.id,s.name from students as s; +----+--------------+ | id | name | +----+--------------+ | 1 | 小明 | | 2 | 小月月 | | 3 | 彭于晏 | | 4 | 刘德华 | | 5 | 黄蓉 | | 6 | 凤姐 | | 7 | 王祖贤 | | 8 | 周杰伦儿 | | 9 | 程坤 | | 10 | 和珅 | | 11 | 刘亦菲 | | 12 | 金星 | | 13 | 静香 | | 14 | 郭靖 | | 15 | 周杰 | | 16 | 钱小豪 | | 17 | 谢霆锋 | | 18 | 陈冠希 | +----+-------------+
6>消除重复行查询
对于students表的age列有重复,可以用distinct去重复查询
MariaDB [testdb]> select distinct age from students; +------+ | age | +------+ | 18 | | 19 | | 28 | | 58 | | 108 | | 44 | | 52 | | 34 | | 55 | | 29 | | 45 | | 22 | | 33 | | 56 | | 38 |
7> 条件查询
#查询年纪大于18岁的信息 MariaDB [testdb]> select * from students where age > 18; +----+--------------+------+--------+--------+--------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+--------------+------+--------+--------+--------+-----------+ | 2 | 小月月 | 19 | 180.00 | 男 | 2 | | | 3 | 彭于晏 | 28 | 185.00 | 男 | 1 | | | 4 | 刘德华 | 58 | 175.00 | 男 | 2 | | | 5 | 黄蓉 | 108 | 160.00 | 女 | 1 | | | 6 | 凤姐 | 44 | 150.00 | 保密 | 2 | | | 7 | 王祖贤 | 52 | 170.00 | 女 | 1 | | | 8 | 周杰伦儿 | 34 | NULL | 男 | 1 | | | 9 | 程坤 | 44 | 181.00 | 男 | 2 | | | 10 | 和珅 | 55 | 166.00 | 男 | 2 | | | 11 | 刘亦菲 | 29 | 162.00 | 女 | 3 | | | 12 | 金星 | 45 | 180.00 | 中性 | 4 | | | 14 | 郭靖 | 22 | 167.00 | 男 | 5 | | | 15 | 周杰 | 33 | 178.00 | 男 | 1 | | | 16 | 钱小豪 | 56 | 178.00 | 男 | 1 | | | 17 | 谢霆锋 | 38 | 175.00 | 男 | 1 | | | 18 | 陈冠希 | 38 | 175.00 | 男 | 1 | | +----+--------------+------+--------+--------+--------+-----------+ #查询年龄介于18岁到28岁之间的 MariaDB [testdb]> select * from students where age between 18 and 28; MariaDB [testdb]> select * from students where age>=18 and age<=28; +----+-----------+------+--------+--------+--------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+-----------+------+--------+--------+--------+-----------+ | 1 | 小明 | 18 | 180.00 | 男 | 1 | | | 2 | 小月月 | 19 | 180.00 | 男 | 2 | | | 3 | 彭于晏 | 28 | 185.00 | 男 | 1 | | | 13 | 静香 | 18 | 170.00 | 女 | 4 | | | 14 | 郭靖 | 22 | 167.00 | 男 | 5 | | #查询年龄18岁以上或者身高180上 MariaDB [testdb]> select * from students where age>18 or high>180; +----+---------------+------+--------+--------+--------+-----------+ | id | name | age | high |gender |cls_id |is_delete | +----+---------------+------+--------+-------+---------+-----------+ | 2 | 小月月 | 19 | 180.00 | 男 | 2 | | | 3 | 彭于晏 | 28 | 185.00 | 男 | 1 | | | 4 | 刘德华 | 58 | 175.00 | 男 | 2 | | | 5 | 黄蓉 | 108 | 160.00 | 女 | 1 | | | 6 | 凤姐 | 44 | 150.00 | 保密 | 2 | | | 7 | 王祖贤 | 52 | 170.00 | 女 | 1 | | | 8 | 周杰伦儿 | 34 | NULL | 男 | 1 | | | 9 | 程坤 | 44 | 181.00 | 男 | 2 | | | 10 | 和珅 | 55 | 166.00 | 男 | 2 | | | 11 | 刘亦菲 | 29 | 162.00 | 女 | 3 | | | 12 | 金星 | 45 | 180.00 | 中性 | 4 | | | 14 | 郭靖 | 22 | 167.00 | 男 | 5 | | | 15 | 周杰 | 33 | 178.00 | 男 | 1 | | | 16 | 钱小豪 | 56 | 178.00 | 男 | 1 | | | 17 | 谢霆锋 | 38 | 175.00 | 男 | 1 | | | 18 | 陈冠希 | 38 | 175.00 | 男 | 1 | | +----+--------------+------+--------+---------+--------+----------+
8> 模糊查询
like
% 替代0个或多个,与shell里的命令*相同
__ 代表一个字符
#查询名字中带有锋的数据 MariaDB [testdb]> select * from students where name like '%锋%'; +----+-----------+------+---------+--------+--------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+-----------+------+---------+--------+--------+-----------+ | 17 | 谢霆锋 | 38 | 175.00 | 男 | 1 | | +----+-----------+------+---------+--------+--------+-----------+ #查询名字是两个字的数据 MariaDB [testdb]> select * from students where name like '__'; +----+--------+------+--------+--------+--------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+--------+------+--------+--------+--------+-----------+ | 1 | 小明 | 18 | 180.00 | 男 | 1 | | | 5 | 黄蓉 | 108 | 160.00 | 女 | 1 | | | 6 | 凤姐 | 44 | 150.00 | 保密 | 2 | | | 9 | 程坤 | 44 | 181.00 | 男 | 2 | | | 10 | 和珅 | 55 | 166.00 | 男 | 2 | | | 12 | 金星 | 45 | 180.00 | 中性 | 4 | | | 13 | 静香 | 18 | 170.00 | 女 | 4 | | | 14 | 郭靖 | 22 | 167.00 | 男 | 5 | | | 15 | 周杰 | 33 | 178.00 | 男 | 1 | | +----+--------+------+--------+--------+--------+-----------+ #查找名字至少三个字以上的数据 MariaDB [testdb]> select * from students where name like '___%'; +----+--------------+------+--------+--------+--------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+--------------+------+--------+--------+--------+-----------+ | 2 | 小月月 | 19 | 180.00 | 男 | 2 | | | 3 | 彭于晏 | 28 | 185.00 | 男 | 1 | | | 4 | 刘德华 | 58 | 175.00 | 男 | 2 | | | 7 | 王祖贤 | 52 | 170.00 | 女 | 1 | | | 8 | 周杰伦儿 | 34 | NULL | 男 | 1 | | | 11 | 刘亦菲 | 29 | 162.00 | 女 | 3 | | | 16 | 钱小豪 | 56 | 178.00 | 男 | 1 | | | 17 | 谢霆锋 | 38 | 175.00 | 男 | 1 | | | 18 | 陈冠希 | 38 | 175.00 | 男 | 1 | | +----+--------------+------+--------+--------+--------+-----------+
#查询名字中带有锋的数据 MariaDB [testdb]> select * from students where name like '%锋%'; +----+-----------+------+---------+--------+--------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+-----------+------+---------+--------+--------+-----------+ | 17 | 谢霆锋 | 38 | 175.00 | 男 | 1 | | +----+-----------+------+---------+--------+--------+-----------+ #查询名字是两个字的数据 MariaDB [testdb]> select * from students where name like '__'; +----+--------+------+--------+--------+--------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+--------+------+--------+--------+--------+-----------+ | 1 | 小明 | 18 | 180.00 | 男 | 1 | | | 5 | 黄蓉 | 108 | 160.00 | 女 | 1 | | | 6 | 凤姐 | 44 | 150.00 | 保密 | 2 | | | 9 | 程坤 | 44 | 181.00 | 男 | 2 | | | 10 | 和珅 | 55 | 166.00 | 男 | 2 | | | 12 | 金星 | 45 | 180.00 | 中性 | 4 | | | 13 | 静香 | 18 | 170.00 | 女 | 4 | | | 14 | 郭靖 | 22 | 167.00 | 男 | 5 | | | 15 | 周杰 | 33 | 178.00 | 男 | 1 | | +----+--------+------+--------+--------+--------+-----------+ #查找名字至少三个字以上的数据 MariaDB [testdb]> select * from students where name like '___%'; +----+--------------+------+--------+--------+--------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+--------------+------+--------+--------+--------+-----------+ | 2 | 小月月 | 19 | 180.00 | 男 | 2 | | | 3 | 彭于晏 | 28 | 185.00 | 男 | 1 | | | 4 | 刘德华 | 58 | 175.00 | 男 | 2 | | | 7 | 王祖贤 | 52 | 170.00 | 女 | 1 | | | 8 | 周杰伦儿 | 34 | NULL | 男 | 1 | | | 11 | 刘亦菲 | 29 | 162.00 | 女 | 3 | | | 16 | 钱小豪 | 56 | 178.00 | 男 | 1 | | | 17 | 谢霆锋 | 38 | 175.00 | 男 | 1 | | | 18 | 陈冠希 | 38 | 175.00 | 男 | 1 | | +----+--------------+------+--------+--------+--------+-----------+
9> 范围查询
in (1,3,8)表示在一个非连续的范围内
between…and
not between…and 表示否定
#查询年龄为18、34、58的人 MariaDB [testdb]> select * from students where age in(18,34,58); +----+--------------+------+--------+--------+--------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+--------------+------+--------+--------+--------+-----------+ | 1 | 小明 | 18 | 180.00 | 男 | 1 | | | 4 | 刘德华 | 58 | 175.00 | 男 | 2 | | | 8 | 周杰伦儿 | 34 | NULL | 男 | 1 | | | 13 | 静香 | 18 | 170.00 | 女 | 4 | | +----+--------------+-------+--------+-------+--------+-----------+ #查询年龄不在18到34岁的人 MariaDB [testdb]> select * from students where age not between 18 and 34; +----+--------+------+--------+--------+--------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+--------+------+--------+--------+--------+-----------+ | 4 | 刘德华 | 58 | 175.00 | 男 | 2 | | | 5 | 黄蓉 | 108 | 160.00 | 女 | 1 | | | 6 | 凤姐 | 44 | 150.00 | 保密 | 2 | | | 7 | 王祖贤 | 52 | 170.00 | 女 | 1 | | | 9 | 程坤 | 44 | 181.00 | 男 | 2 | | | 10 | 和珅 | 55 | 166.00 | 男 | 2 | | | 12 | 金星 | 45 | 180.00 | 中性 | 4 | | | 16 | 钱小豪 | 56 | 178.00 | 男 | 1 | | | 17 | 谢霆锋 | 38 | 175.00 | 男 | 1 | | | 18 | 陈冠希 | 38 | 175.00 | 男 | 1 | |
10> 空判断
判断is null
#查询身高为空的数据信息 MariaDB [testdb]> select * from students where high is null; +----+--------------+------+------+--------+--------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+--------------+------+------+--------+--------+-----------+ | 8 | 周杰伦儿 | 34 | NULL | 男 | 1 | | +----+--------------+------+------+--------+--------+-----------+
11>排序
order by 字段;
asc从小到大排列,即升序,默认为此排序;
desc从大到小排序,即降序;
#按照年纪从大到小排序 MariaDB [testdb]> select * from students order by age desc; +----+--------------+------+--------+--------+--------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+--------------+------+--------+--------+--------+-----------+ | 5 | 黄蓉 | 108 | 160.00 | 女 | 1 | | | 4 | 刘德华 | 58 | 175.00 | 男 | 2 | | | 16 | 钱小豪 | 56 | 178.00 | 男 | 1 | | | 10 | 和珅 | 55 | 166.00 | 男 | 2 | | | 7 | 王祖贤 | 52 | 170.00 | 女 | 1 | | | 12 | 金星 | 45 | 180.00 | 中性 | 4 | | | 6 | 凤姐 | 44 | 150.00 | 保密 | 2 | | | 9 | 程坤 | 44 | 181.00 | 男 | 2 | | | 17 | 谢霆锋 | 38 | 175.00 | 男 | 1 | | | 18 | 陈冠希 | 38 | 175.00 | 男 | 1 | | | 8 | 周杰伦儿 | 34 | NULL | 男 | 1 | | | 15 | 周杰 | 33 | 178.00 | 男 | 1 | | | 11 | 刘亦菲 | 29 | 162.00 | 女 | 3 | | | 3 | 彭于晏 | 28 | 185.00 | 男 | 1 | | | 14 | 郭靖 | 22 | 167.00 | 男 | 5 | | | 2 | 小月月 | 19 | 180.00 | 男 | 2 | | | 13 | 静香 | 18 | 170.00 | 女 | 4 | | | 1 | 小明 | 18 | 180.00 | 男 | 1 | | +----+-------------+------+------- -+-------+--------+-----------+ #查询年纪在18到34 岁之间的男性,按照年纪从大到小排序 MariaDB [testdb]> select * from students where gender=1 and age between 18 and 34 order by age desc; #可读性差 MariaDB [testdb]> select * from students where (age between 18 and 34) and gender=1 order by age desc; +----+--------------+------+--------+--------+--------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+--------------+------+--------+--------+--------+-----------+ | 8 | 周杰伦儿 | 34 | NULL | 男 | 1 | | | 15 | 周杰 | 33 | 178.00 | 男 | 1 | | | 3 | 彭于晏 | 28 | 185.00 | 男 | 1 | | | 14 | 郭靖 | 22 | 167.00 | 男 | 5 | | | 2 | 小月月 | 19 | 180.00 | 男 | 2 | | | 1 | 小明 | 18 | 180.00 | 男 | 1 | | +----+--------------+------+--------+--------+--------+-----------+ #order by 多字段 #按年龄从打大小后再按身高从大到小排序 MariaDB [testdb]> select * from students order by age desc,high desc; +----+----------+------+--------+--------+--------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+----------+------+--------+--------+--------+-----------+ | 5 | 黄蓉 | 108 | 160.00 | 女 | 1 | | | 4 | 刘德华 | 58 | 175.00 | 男 | 2 | | | 16 | 钱小豪 | 56 | 178.00 | 男 | 1 | | | 10 | 和珅 | 55 | 166.00 | 男 | 2 | | | 7 | 王祖贤 | 52 | 170.00 | 女 | 1 | | | 12 | 金星 | 45 | 180.00 | 中性 | 4 | | | 9 | 程坤 | 44 | 181.00 | 男 | 2 | | | 6 | 凤姐 | 44 | 150.00 | 保密 | 2 | | | 17 | 谢霆锋 | 38 | 175.00 | 男 | 1 | | | 18 | 陈冠希 | 38 | 175.00 | 男 | 1 | | | 8 | 周杰伦儿 | 34 | NULL | 男 | 1 | | | 15 | 周杰 | 33 | 178.00 | 男 | 1 | | | 11 | 刘亦菲 | 29 | 162.00 | 女 | 3 | | | 3 | 彭于晏 | 28 | 185.00 | 男 | 1 | | | 14 | 郭靖 | 22 | 167.00 | 男 | 5 | | | 2 | 小月月 | 19 | 180.00 | 男 | 2 | | | 1 | 小明 | 18 | 180.00 | 男 | 1 | | | 13 | 静香 | 18 | 170.00 | 女 | 4 | | +----+----------+------+--------+--------+--------+-----------+
12> 聚合函数
总数(量) count
最大值 max
最小值 min
平均数avg
#统计总共有多少条数据 MariaDB [testdb]> select count(*) from students; #*号统计的数据最准确,count的括号里可以跟字段用来统计某个字段共有多少条有效数据数据, +----------+ | count(*) | +----------+ | 18 | +----------+ #查询总共有多少女性数据 MariaDB [testdb]> select count(*) from students where gender=2; +----------+ | count(*) | +----------+ | 4 | +----------+ 1 row in set (0.000 sec) #查看年龄最大的数据 MariaDB [testdb]> select max(age) from students; +----------+ | max(age) | +----------+ | 108 | +----------+ #查看年纪最大的人名 MariaDB [testdb]> select name,max(age) from students; #这样统计出来是错的 +--------+----------+ | name | max(age) | +--------+----------+ | 小明 | 108 | +--------+----------+ #可以从大到小分组之后分页选出第一条数据,即可。 #查看女性的最高身高 MariaDB [testdb]> select max(high) from students where gender=2; +-----------+ | max(high) | +-----------+ | 70.00 | #求年纪和并设置别名 MariaDB [testdb]> select sum(age) as '年纪总和' from students; +--------------+ | 年纪总和 | +--------------+ | 739 | +--------------+ #求年纪的平均和 MariaDB [testdb]> select avg(age) as '平均年龄' from students; MariaDB [testdb]> select sum(age)/count(*) as '平均年纪' from students; +--------------+ | 平均年纪 | +--------------+ | 41.0556 | +--------------+1 row in set (0.001 sec) #保留年纪两位小数,用round函数 MariaDB [testdb]> select round(sum(age)/count(*),2) as '平均年纪' from students; +--------------+ | 平均年纪 | +--------------+ | 41.06 | +--------------+
聚合函数通常是和分组一起使用的。
13> 分组
group by
having函数
#按性别(gender)分组 MariaDB [testdb]> select gender from students group by gender; #第一个gender为组名 +--------+ | gender | +--------+ | 男 | | 女 | | 中性 | | 保密 | +-------+
#显示每组人的个数 MariaDB [testdb]> select gender,count(*) from students group by gender; +---------+----------+ | gender | count(*) | +---------+----------+ | 男 | 12 | | 女 | 4 | | 中性 | 1 | | 保密 | 1 | +--------+------------+ #查看男性组中成员姓名 MariaDB [testdb]> select gender,group_concat(name) from students where gender=1 group by gender; #group_gender 按组显示 #查看每组成员的name、age、high,用空格分割(自定义分隔符) MariaDB [testdb]> select gender,group_concat(name,' ',age,' ',high) from students group by gender; #分隔符加单引号,可以自定义分隔符,如/、|等 | 男 | 小明 18 180.00,谢霆锋 38 175.00,钱小豪 56 178.00,周杰 33 178.00,郭靖 22 167.00,和珅 55 166.00,程坤 44 181.00,陈冠希 38 175.00,小月月 19 180.00,彭于晏 28 185.00,刘德华 58 175.00 | | 女 | 黄蓉 108 160.00,静香 18 170.00,刘亦菲 29 162.00,王祖贤 52 170.00 | | 中性 | 金星 45 180.00 | | 保密 | 凤姐 44 150.00 #看到group by分组,用条件表达式首先应想到用函数having,而不是where。 #查询平均年纪大于40 的组 MariaDB [testdb]> select gender,avg(age) from students group by gender having avg(age)>40; +--------+----------+ | gender | avg(age) | +--------+----------+ | 女 | 51.7500 | | 中性 | 45.0000 | | 保密 | 44.0000 | +--------+----------+ #查看人数多于4个的组 MariaDB [testdb]> select gender,group_concat(name) from students group by gender having count(*)>4; 男 | 小明,谢霆锋,钱小豪,周杰,郭靖,和珅,程坤,周杰伦儿,陈冠希,小月月,彭于晏,刘德华
14> 分页 l
imit num1 num2 :显示第num1后的num2行,num2相当于步长
当数据信息较大时,可以通过分页显示部分信息,减缓内存压力
#根据年龄从大到小排序,通过分页只显示一条信息(即显示年龄最大的用户数据) MariaDB [testdb]> select * from students order by age desc limit 1; #显示一行 +----+--------+------+--------+--------+--------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+--------+------+--------+--------+--------+-----------+ | 5 | 黄蓉 | 108 | 160.00 | 女 | 1 | | +----+--------+------+--------+--------+--------+-----------+ MariaDB [testdb]> select * from students order by age desc limit 2; MariaDB [testdb]> select * from students order by age desc limit 0,2; #显示两条数据
+----+-----------+------+--------+--------+--------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+-----------+------+--------+--------+--------+-----------+ | 5 | 黄蓉 | 108 | 160.00 | 女 | 1 | | | 4 | 刘德华 | 58 | 175.00 | 男 | 2 | | +----+-----------+------+--------+--------+---------+-----------+ MariaDB [testdb]> select * from students order by age desc limit 1,3; #显示第1行后面的3行,从2开始的3行,即234行 +----+-----------+------+--------+--------+--------+-----------+ | id | name | age | high | gender | cls_id | is_delete | +----+-----------+------+--------+--------+--------+-----------+ | 4 | 刘德华 | 58 | 175.00 | 男 | 2 | | | 16 | 钱小豪 | 56 | 178.00 | 男 | 1 | | | 10 | 和珅 | 55 | 166.00 | 男 | 2 | | +----+-----------+------+--------+--------+--------+-----------+
2. 连接查询
连接查询即多个表查询,包括内关联、外关联查询和自关联查询。例如创建的classes和students两个表通过classes.id和students.cls_id联系起来属于内关联查询,而外关联查询包括左关联和右关联,左右之分是按查询基础来区分的,如左关联以左边的表为基础,右关联以右边的表为基础。内外关联只是在查询时通过设定的标识来进行联系,但他们并没有什么联系,让他们真正有联系的是外键的作用,而自关联不同,比如地区的规划,省市区街道等,若每个规划阶段有一个表,各个表通过外键构成子父关系,而且各个表的各个字段都相同,因此可以通过自己关联自己建在一个表里面来实现自关联而不通过外键实现关联。自关联可以通过以下的表来了解:
id |
name |
f |
|
省份 |
1 |
北京市 |
null |
2 |
天津市 |
null |
|
3 |
河北省 |
null |
|
4 |
山西省 |
null |
|
地级市 |
5 |
海淀区 |
1 |
6 |
滨海区 |
2 |
|
7 |
沧州市 |
3 |
|
8 |
大同市 |
4 |
|
9 |
朝阳区 |
1 |
|
10 |
武清区 |
2 |
|
11 |
石家庄 |
3 |
|
12 |
太原市 |
4 |
|
县级市 |
13 |
西二旗 |
5 |
14 |
大港 |
6 |
|
15 |
任丘市 |
7 |
|
16 |
清徐 |
8 |
|
17 |
中关村 |
5 |
|
18 |
汉沽 |
6 |
|
19 |
河间市 |
7 |
|
20 |
阳曲 |
8 |
单独一个表通过id和f进行关联,如海淀区f=1对应北京市id=1,中关村f=5对应海淀区id=5,通过自关联构成了一条完整的子父连接,北京市--海淀区--中关村、 天津市--滨海区--大港等。
2.1 内关联查询
1)给class表里写入数据用作实验
MariaDB [testdb]> ;create table classes( #创建classes表 -> id int unsigned auto_increment primary key not null, -> name varchar(20) not null -> ); MariaDB [testdb]> insert into classes values (0, '云唯_01期'),(0, '云唯_02期'); Query OK, 2 rows affected (0.003 sec) Records: 2 Duplicates: 0 Warnings: 0 MariaDB [testdb]> select * from classes; +----+------------------+ | id | name | +----+------------------+ | 1 | 云唯_01期 | | 2 | 云唯_02期 | +----+------------------+
2) 连接查询(内关联查询)
#两个表连接起来取交集查询 MariaDB [testdb]> select * from classes inner join students on classes.id=students.cls_id; #内连接;首选条件语句为on +----+--------------+----+--------------+------+--------+--------+--------+-----------+ | id | name | id | name | age | high | gender | cls_id | is_delete | +----+--------------+----+--------------+------+--------+--------+--------+-----------+ | 1 | 云唯_01期 | 1 | 小明 | 18 | 180.00 | 男 | 1 | | | 2 | 云唯_02期 | 2 | 小月月 | 19 | 180.00 | 男 | 2 | | | 1 | 云唯_01期 | 3 | 彭于晏 | 28 | 185.00 | 男 | 1 | | | 2 | 云唯_02期 | 4 | 刘德华 | 58 | 175.00 | 男 | 2 | | | 1 | 云唯_01期 | 5 | 黄蓉 | 108 | 160.00 | 女 | 1 | | | 2 | 云唯_02期 | 6 | 凤姐 | 44 | 150.00 | 保密 | 2 | | | 1 | 云唯_01期 | 7 | 王祖贤 | 52 | 170.00 | 女 | 1 | | | 1 | 云唯_01期 | 8 | 周杰伦儿 | 34 | NULL | 男 | 1 | | | 2 | 云唯_02期 | 9 | 程坤 | 44 | 181.00 | 男 | 2 | | | 2 | 云唯_02期 | 10 | 和珅 | 55 | 166.00 | 男 | 2 | | | 1 | 云唯_01期 | 15 | 周杰 | 33 | 178.00 | 男 | 1 | | | 1 | 云唯_01期 | 16 | 钱小豪 | 56 | 178.00 | 男 | 1 | | | 1 | 云唯_01期 | 17 | 谢霆锋 | 38 | 175.00 | 男 | 1 | | | 1 | 云唯_01期 | 18 | 陈冠希 | 38 | 175.00 | 男 | 1 | | +----+--------------+----+--------------+------+--------+--------+--------+-----------+ #仅显示班级和姓名字段 MariaDB [testdb]> select classes.name,students.name from classes inner join students on classes.id=students.cls_id; MariaDB [testdb]> select c.name,s.name from classes as c inner join students as s on c.id=s.cls_id; # 别名 MariaDB [testdb]> select c.name,s.name from classes as c inner join students as s on c.id=s.cls_id order by c.name; #以班级名排序 +-------------+--------------+ | name | name | +-------------+--------------+ | 云唯_01期 | 小明 | | 云唯_01期 | 彭于晏 | | 云唯_01期 | 黄蓉 | | 云唯_01期 | 王祖贤 | | 云唯_01期 | 周杰 | | 云唯_01期 | 谢霆锋 | | 云唯_01期 | 周杰伦儿 | | 云唯_01期 | 钱小豪 | | 云唯_01期 | 陈冠希 | | 云唯_02期 | 程坤 | | 云唯_02期 | 小月月 | | 云唯_02期 | 刘德华 | | 云唯_02期 | 凤姐 | | 云唯_02期 | 和珅 | +-------------+--------------+
可以看到,显示的仅是cls_id 为1、2的数据,即和classes.id一一对应的数据,并没有查询到cls_id为345的数据。这便是内关联查询的效果。
2.2 外关联查询
1)左右关联
#继续以classes表和students表为例 #左关联: MariaDB [testdb]> select c.name,s.name from classes as c left join students as s on c.id=s.cls_id order by c.name; #以左边的c.name为基准查询,只能查询到cls-id位为1、2的数据 +--------------+--------------+ | name | name | +--------------+--------------+ | 云唯_01期 | 小明 | | 云唯_01期 | 彭于晏 | | 云唯_01期 | 黄蓉 | | 云唯_01期 | 王祖贤 | | 云唯_01期 | 周杰 | | 云唯_01期 | 谢霆锋 | | 云唯_01期 | 周杰伦儿 | | 云唯_01期 | 钱小豪 | | 云唯_01期 | 陈冠希 | | 云唯_02期 | 程坤 | | 云唯_02期 | 小月月 | | 云唯_02期 | 刘德华 | | 云唯_02期 | 凤姐 | | 云唯_02期 | 和珅 | +--------------+--------------+ #右关联: MariaDB [testdb]> select c.name,s.name from classes as c right join students as s on c.id=s.cls_id order by c.name; #以s.name为基准,cls_id取值为12345,而c.name仅支持12,所以钱44条数据为空(null) +--------------+-------------+ | name | name | +--------------+-------------+ | NULL | 金星 | | NULL | 郭靖 | | NULL | 刘亦菲 | | NULL | 静香 | | 云唯_01期 | 周杰伦儿 | | 云唯_01期 | 钱小豪 | | 云唯_01期 | 陈冠希 | | 云唯_01期 | 小明 | | 云唯_01期 | 彭于晏 | | 云唯_01期 | 黄蓉 | | 云唯_01期 | 王祖贤 | | 云唯_01期 | 周杰 | | 云唯_01期 | 谢霆锋 | | 云唯_02期 | 小月月 | | 云唯_02期 | 刘德华 | | 云唯_02期 | 凤姐 | | 云唯_02期 | 和珅 | | 云唯_02期 | 程坤 | +--- ---------+- ------------+
2.3 自 关联查询
1)创建areas表用作实验
MariaDB [testdb]> create table areas( -> aid int primary key auto_increment, -> name varchar(20), -> pid int -> ); MariaDB [testdb]> show tables; +--------------------+ | Tables_in_testdb | +--------------------+ | areas | | classes | | students | --写入数据 --省份 insert into areas(aid,name,pid) values(1,'北京市',null); insert into areas(aid,name,pid) values(0,'天津市',null); insert into areas(aid,name,pid) values(0,'河北省',null); insert into areas(aid,name,pid) values(0,'山西省',null); --地级市 insert into areas(aid,name,pid) values(0,'海淀区',1); insert into areas(aid,name,pid) values(0,'滨海区',2); insert into areas(aid,name,pid) values(0,'沧州市',3); insert into areas(aid,name,pid) values(0,'大同市',4); insert into areas(aid,name,pid) values(0,'朝阳区',1); insert into areas(aid,name,pid) values(0,'武清区',2); insert into areas(aid,name,pid) values(0,'石家庄',3); insert into areas(aid,name,pid) values(0,'太原市',4); --县级市 insert into areas(aid,name,pid) values(0,'西二旗',5); insert into areas(aid,name,pid) values(0,'大港',6); insert into areas(aid,name,pid) values(0,'任丘市',7); insert into areas(aid,name,pid) values(0,'清徐',8); insert into areas(aid,name,pid) values(0,'中关村',5); insert into areas(aid,name,pid) values(0,'汉沽',6); insert into areas(aid,name,pid) values(0,'河间市',7); insert into areas(aid,name,pid) values(0,'阳曲',8); MariaDB [testdb]> select * from areas; +-----+-----------+------+ | aid | name | pid | +-----+-----------+------+ | 1 | 北京市 | NULL | | 2 | 天津市 | NULL | | 3 | 河北省 | NULL | | 4 | 山西省 | NULL | | 5 | 海淀区 | 1 | | 6 | 滨海区 | 2 | | 7 | 沧州市 | 3 | | 8 | 大同市 | 4 | | 9 | 朝阳区 | 1 | | 10 | 武清区 | 2 | | 11 | 石家庄 | 3 | | 12 | 太原市 | 4 | | 13 | 西二旗 | 5 | | 14 | 大港 | 6 | | 15 | 任丘市 | 7 | | 16 | 清徐 | 8 | | 17 | 中关村 | 5 | | 18 | 汉沽 | 6 | | 19 | 河间市 | 7 | | 20 | 阳曲 | 8 | +-----+----------+------+
2)自关联查询
--查询北京市的所有区: MariaDB [testdb]> select * from areas as p inner join areas as q on p.aid=q.pid where p.name='北京市'; #起别名,自关联 +-----+-----------+------+-----+-----------+------+ | aid | name | pid | aid | name | pid | +-----+-----------+------+-----+-----------+------+ | 1 | 北京市 | NULL | 5 | 海淀区 | 1 | | 1 | 北京市 | NULL | 9 | 朝阳区 | 1 | +-----+-----------+------+-----+-----------+------+ 2 rows in set (0.000 sec) --查询山西省的所有区: MariaDB [testdb]> select * from areas as p inner join areas as q on p.aid=q.pid where p.name='山西省'; +-----+-----------+------+-----+-----------+------+ | aid | name | pid | aid | name | pid | +-----+-----------+------+-----+-----------+------+ | 4 | 山西省 | NULL | 8 |大同市 | 4 | | 4 | 山西省 | NULL | 12 |太原市 | 4 | +-----+-----------+------+-----+-----------+------+
3)子查询(嵌套查询)
#查询北京市所有的区 MariaDB [testdb]> select * from areas where pid=(select aid from areas where name='北京市'); +-----+-----------+-------+ | aid | name | pid | +-----+-----------+-------+ | 5 | 海淀区 | 1 | | 9 | 朝阳区 | 1 | +-----+-----------+-------+ 2 rows in set (0.001 sec)