单表查询
本文将向您介绍如何使用 SQL 语句进行 seekdb 中的单表查询操作。
前提条件
语法
请使用 SELECT 语句进行查询数据。
SELECT 语句单表查询的一般结构如下:
SELECT [ALL | DISTINCT | UNIQUE | SQL_CALC_FOUND_ROWS] select_list
FROM table_name
[ WHERE query_condition ]
[ GROUP BY group_by_condition ]
[ HAVING group_condition ]
[ ORDER BY column_list ][ASC | DESC]
[ LIMIT limit_clause ]
column_list:
column_name[,column_name...]
参数解释:
| 参数 | 说明 |
|---|---|
| select_list | 要检索的列的列表,可以是列名、表达式、聚合函数等。可以使用逗号分隔多个列。 |
| table_name | 要检索数据的表的名称。 |
| WHERE query_condition | 可选参数,用于指定检索的条件。只有符合条件的行才会被返回。 |
| GROUP BY group_by_condition | 可选参数,用于按照指定的列对结果进行分组。通常与聚合函数一起使用。 |
| HAVING group_condition | 可选参数,用于过滤分组后的结果集,只返回满足条件的分组。 |
| ORDER BY column_list | 可选参数,用于对结果集进行排序。可以指定一个或多个列进行排序。 |
| ASC | DESC |
| LIMIT limit_clause | 可选参数,用于限制返回的结果集的行数。 |
| column_list | 用于指定要检索的列的参数,可以是单个列或多个列,用逗号分隔。 |
| column_name | 要检索的列的名称。 |
SELECT 关键字执行顺序简 介
当 WHERE、GROUP BY、HAVING、ORDER BY、LIMIT 这些关键字一起使用时,先后顺序有明确的限制。关键字执行顺序如下:
-
执行
FROM找到表。 -
执行
WHERE指定约束条件。 -
执行
GROUP BY将取出的每条记录进行分组(聚合)。如果没有GROUP BY,则整体作为一组。 -
执行
HAVING将分组的结果进行筛选。 -
执行
SELECT。 -
执行
DISTINCT去重。 -
执行
ORDER BY将结果按条件升序或降序排序。 -
执行
LIMIT限制结果的条数。
WHERE 和 HAVING 的区别是,WHERE 是在分组前对数据进行筛选,而 HAVING 是在分组后的结果里进 行筛选,最后返回整个 SQL 的查询结果。
创建测试表并添加测试数据
-
创建表
student。CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
gender TINYINT NOT NULL,
age INT NOT NULL,
score FLOAT NOT NULL,
enrollment_date DATE NOT NULL,
notes VARCHAR(50)
); -
向表
student中插入 10 条数据。INSERT INTO student (name, gender, age, score, enrollment_date, notes)
VALUES ('Emma', 0, 20, 85.0, '2021-09-01',NULL),
('William', 1, 21, 90.5, '2021-09-02','B'),
('Olivia', 0, 19, 95.5, '2021-09-03','A'),
('James', 1, 20, 87.5, '2021-09-03',NULL),
('Sophia', 0, 20, 91.5, '2021-09-05','B'),
('Benjamin', 1, 21, 96.5, '2021-09-01','A'),
('Ava', 0, 22, 89.5, '2021-09-06',NULL),
('Michael', 1, 18, 93.5, '2021-09-08','B'),
('Charlotte', 1, 19, 88.0, '2021-09-06',NULL),
('Ethan', 1, 20, 92.0, '2021-09-01','B'); -
创建表
fruit_order。CREATE TABLE fruit_order(
order_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '订单ID',
user_id BIGINT NOT NULL COMMENT '客户ID',
user_name VARCHAR(16) NOT NULL DEFAULT '' COMMENT '客户名称',
fruit_price DECIMAL(10,2) NOT NULL DEFAULT 0 COMMENT '订单金额',
order_year SMALLINT NOT NULL COMMENT '下单年份'
) COMMENT '订单表'; -
向表
fruit_order中插入 10 条数据。INSERT INTO fruit_order(user_id, user_name,fruit_price,order_year)
VALUES (1011,'A1',13.11,'2019'),
(1011,'A1',22.21,'2020'),
(1011,'A1',58.83,'2020'),
(1022,'B2',23.34,'2019'),
(1022,'B2',12.22,'2019'),
(1022,'B2',14.66,'2021'),
(1022,'B2',34.44,'2021'),
(1033,'C3',51.55,'2020'),
(1033,'C3',63.66,'2021'),
(1034,'D4',53.62,'2021');
基本查询
在使用 SELECT 时,建议使用有意义的列别名和合适的列顺序,可以提高结果集的可读性、更好地组织和理解查询结果。
查询全部列
-
可以通过
SELECT * FROM student;语句将全部学生信息查询出来。 -
也可以手动列出所有字段,通过
SELECT id,name,gender,age,score,enrollment_date FROM student;语句将全部学生信息查询出来。
虽然使用 * 可以快速列出所有字段,但是使用手动列出所有字段在查询性能、代码的可读性和可维护性方面会更好。
示例 1:使用下面的 SQL 语句,查询表 student 中所有行的数据。
SELECT id, name, gender, age, score, enrollment_date, notes
FROM student;
或者
SELECT * FROM student;
返回结果如下:
+----+-----------+--------+-----+-------+-----------------+-------+
| id | name | gender | age | score | enrollment_date | notes |
+----+-----------+--------+-----+-------+-----------------+-------+
| 1 | Emma | 0 | 20 | 85 | 2021-09-01 | NULL |
| 2 | William | 1 | 21 | 90.5 | 2021-09-02 | B |
| 3 | Olivia | 0 | 19 | 95.5 | 2021-09-03 | A |
| 4 | James | 1 | 20 | 87.5 | 2021-09-03 | NULL |
| 5 | Sophia | 0 | 20 | 91.5 | 2021-09-05 | B |
| 6 | Benjamin | 1 | 21 | 96.5 | 2021-09-01 | A |
| 7 | Ava | 0 | 22 | 89.5 | 2021-09-06 | NULL |
| 8 | Michael | 1 | 18 | 93.5 | 2021-09-08 | B |
| 9 | Charlotte | 1 | 19 | 88 | 2021-09-06 | NULL |
| 10 | Ethan | 1 | 20 | 92 | 2021-09-01 | B |
+----+-----------+--------+-----+-------+-----------------+-------+
10 rows in set
查询指定列
在表中根据列名查找指定列数据。
示例 2:使用下面的 SQL 语句,查询表 student 中所有行的数据,返回每行的 id 和 name 列的数据。
SELECT id, name
FROM student;
返回结果如下:
+----+-----------+
| id | name |
+----+-----------+
| 1 | Emma |
| 2 | William |
| 3 | Olivia |
| 4 | James |
| 5 | Sophia |
| 6 | Benjamin |
| 7 | Ava |
| 8 | Michael |
| 9 | Charlotte |
| 10 | Ethan |
+----+-----------+
10 rows in set
查询经过计算的值和指定列别名
在查询中可以对指定列进行数据计算处理。
示例 3:使用下面的 SQL 语句,从表 student 中选择 id、name、age 和 age+5 四个列的数据,并为 age+5 这个计算结果列指定别名 age_plus_5。
SELECT id, name, age, age+5 AS age_plus_5
FROM student;
返回结果如下:
+----+-----------+-----+------------+
| id | name | age | age_plus_5 |
+----+-----------+-----+------------+
| 1 | Emma | 20 | 25 |
| 2 | William | 21 | 26 |
| 3 | Olivia | 19 | 24 |
| 4 | James | 20 | 25 |
| 5 | Sophia | 20 | 25 |
| 6 | Benjamin | 21 | 26 |
| 7 | Ava | 22 | 27 |
| 8 | Michael | 18 | 23 |
| 9 | Charlotte | 19 | 24 |
| 10 | Ethan | 20 | 25 |
+----+-----------+-----+------------+
10 rows in set
更多关于在查询中使用操作符和函数来对指定列进行数据处理的方法,请参见 **在查询中使用操 下面的章节。
数据过滤
要查询满足特定条件的数据时,可以通过在 SELECT 查询语句中添加一个 WHERE 子句来进行数据过滤。WHERE 子句后面可以包含一个或多个条件,这些条件用于筛选数据,只有满足 WHERE 条件的数据才会被返回。可以根据特定需求,通过灵活运用查询条件来过滤和检索目标数据。
在使用 WHERE 子句时,要确保条件正确和使用合适的运算符。
WHERE 子句常用的查询条件如下表所示。
| 查询条件类型 | 谓词 |
|---|---|
| 比较查询 | =,>,<,>=,<=,!=,<> |
| 逻辑查询(多重条件) | AND,OR,NOT |
| 模糊查询(字符匹配) | LIKE,NOT LIKE |
| 区间查询(确定范围) | BETWEEN AND,NOT BETWEEN AND |
| 指定集合查询 | IN,NOT IN |
| NULL 值查询 | IS NULL,IS NOT NULL |
更多有关查询条件运算符的详细信息,请参见 比较运算符。
比较条件查询
等于
等于(=):查询出指定列中和目标值相等的数据。如果值是字符串类型,需要用单引号或者双引号括起来。
示例 4:使用下面的 SQL 语句,查询表 student 中 gender 列等于 1 的所有行,并返回这些行中的 id、name 和 gender 列的数据。
SELECT id, name, gender
FROM student
WHERE gender = 1;
返回结果如下:
+----+-----------+--------+
| id | name | gender |
+----+-----------+--------+
| 2 | William | 1 |
| 4 | James | 1 |
| 6 | Benjamin | 1 |
| 8 | Michael | 1 |
| 9 | Charlotte | 1 |
| 10 | Ethan | 1 |
+----+-----------+--------+
6 rows in set
不等于
不等于包括 <> 和 != 两种写法。
示例 5:使用下面的 SQL 语句,查询表 student 中 gender 列不等于 1 的所有行,并返回这些行中的 id、name 和 gender 列的数据。
SELECT id, name, gender
FROM student
WHERE gender <> 1;
返回结果如下:
+----+--------+--------+
| id | name | gender |
+----+--------+--------+
| 1 | Emma | 0 |
| 3 | Olivia | 0 |
| 5 | Sophia | 0 |
| 7 | Ava | 0 |
+----+--------+--------+
4 rows in set
大于和小于
大于(>)和小于(<)将数值按照大小比较。如果比较的是字符,则按照 ASCII 码对应的值进行比较,比较时按照字符对应的位置逐一进行比较。
大于等于(>=)和小于等于(<=)与之类似。
示例 6:使用下面的 SQL 语句,查询表 student 中 score 列小于 90 的所有行,并返回这些行中的 id、name 和 score 列的数据。
SELECT id, name, score
FROM student
WHERE score < 90;
返回结果如下:
+----+-----------+-------+
| id | name | score |
+----+-----------+-------+
| 1 | Emma | 85 |
| 4 | James | 87.5 |
| 7 | Ava | 89.5 |
| 9 | Charlotte | 88 |
+----+-----------+-------+
4 rows in set
逻辑条件查询
逻辑查询运算符并且(AND)和或者(OR)支持多个条件的查询。
AND
AND 关键字用于将多个条件组合在一起,只有同时满足所有条件的数据才会被返回。
示例 7:使用下面的 SQL 语句,查询表 student 中 gender 等于 1 且 score 小于等于 90 的所有行,并返回这些行中的 id、name、gender 和 score 列的数据。
SELECT id, name, gender, score
FROM student
WHERE gender = 1 AND score <= 90;
返回结果如下:
+----+-----------+--------+-------+
| id | name | gender | score |
+----+-----------+--------+-------+
| 4 | James | 1 | 87.5 |
| 9 | Charlotte | 1 | 88 |
+----+-----------+--------+-------+
2 rows in set
OR
OR 关键字用于将多个条件连接起来,只要满足其中任意一个条件的数据就会被返回。
示例 8:使用下面的 SQL 语句,查询表 student 中 gender 等于 1 或 score 小于 90 的所有行,并返回这些行中的 id、name、gender 和 score 列的数据。
SELECT id, name, gender, score
FROM student
WHERE gender = 1 OR score < 90;
返回结果如下:
+----+-----------+--------+-------+
| id | name | gender | score |
+----+-----------+--------+-------+
| 1 | Emma | 0 | 85 |
| 2 | William | 1 | 90.5 |
| 4 | James | 1 | 87.5 |
| 6 | Benjamin | 1 | 96.5 |
| 7 | Ava | 0 | 89.5 |
| 8 | Michael | 1 | 93.5 |
| 9 | Charlotte | 1 | 88 |
| 10 | Ethan | 1 | 92 |
+----+-----------+--------+-------+
8 rows in set
模糊查询
谓词 LIKE 可以用来进行字符串的模糊匹配。
语法含义是查找对应列值与 pattern 相匹配的数据。pattern 可以是完整的字符串,也可以包含通配符 % 和 _。其中:
-
下划线 (
_) 表示匹配任意一个字符。 -
百分号 (
%) 表示可以匹配值中的零个或多个字符。%不能匹配NULL。
当数据库字集为 ASCII 时一个汉字需要两个 _;当字符集为 GBK 时只需要一个 _。
示例 9:使用下面的 SQL 语句,查询表 student 中 name 包含 am 的所有行,并返回这些行中的 id 和 name 列的数据。
SELECT id, name
FROM student
WHERE name LIKE '%am%';
返回结果如下:
+----+----------+
| id | name |
+----+----------+
| 2 | William |
| 4 | James |
| 6 | Benjamin |
+----+----------+
3 rows in set
区间查询
操作符 BETWEEN ... AND 会选取介于两个值之间的数据。这些值可以是数值、文本或者日期。
区间查询的两个临界值不要调换位置,只能是大于等于左边的值,并且小于等于右边的值。
示例 10:使用下面的 SQL 语句,查询表 student 中 score 值在 85 ~ 90 的所有行,并返回这些行中的 id、name 和 score 列的数据。
SELECT id, name, score
FROM student
WHERE score BETWEEN 85 AND 90;
返回结果如下:
+----+-----------+-------+
| id | name | score |
+----+-----------+-------+
| 1 | Emma | 85 |
| 4 | James | 87.5 |
| 7 | Ava | 89.5 |
| 9 | Charlotte | 88 |
+----+-----------+-------+
4 rows in set
指定集合查询
操作符 IN 在 WHERE 子句指定的多个值,称之为一个集合。IN 表示指定列中的数据只要满足集合中任意一个都会被返回。NOT IN 表示和集合中都不匹配的数据才会被返回。
[NOT] IN集合中的值类型必须一致或相互兼容。[NOT] IN集合中的值不支持通配符。
示例 11:使用下面的 SQL 语句,查询表 student 中 id 值满足在集合 (1, 3, 5, 7) 的所有行,并返回这些行中的 id 和 name 列的数据。
SELECT id, name
FROM student
WHERE id IN (1,3,5,7);
返回结果如下:
+----+--------+
| id | name |
+----+--------+
| 1 | Emma |
| 3 | Olivia |
| 5 | Sophia |
| 7 | Ava |
+----+--------+
4 rows in set
NULL 值专用查询
由于比较运算符、LIKE、BETWEEN AND、IN、NOT IN 对 NULL 值的查询结果不准确,所以建议使用 NULL 值专用查询语句 IS NULL 和 IS NOT NULL。除此之外,还可以使用安全等于(<=>),其既可以判断普通的数值,也可以判断 NULL 值。
IS NULL
IS NULL 条件用于查询指定列的值为 NULL 的数据。
示例 12:使用下面的 SQL 语句,查询表 student 中 notes 为空的所有行,并返回这些行中的 id、name、score 和 notes列的数据。
SELECT id, name, score, notes
FROM student
WHERE notes IS NULL;
返回结果如下:
+----+-----------+-------+-------+
| id | name | score | notes |
+----+-----------+-------+-------+
| 1 | Emma | 85 | NULL |
| 4 | James | 87.5 | NULL |
| 7 | Ava | 89.5 | NULL |
| 9 | Charlotte | 88 | NULL |
+----+-----------+-------+-------+
4 rows in set
IS NOT NULL
IS NOT NULL 条件用于查询指定列的值为非 NULL 的数据。
示例 13:使用下面的 SQL 语句,查询表 student 中 notes 不为空的所有行,并返回这些行中的 id、name、score、和 notes 列的数据。
SELECT id, name, score, notes
FROM student
WHERE notes IS NOT NULL;
返回结果如下:
+----+----------+-------+-------+
| id | name | score | notes |
+----+----------+-------+-------+
| 2 | William | 90.5 | B |
| 3 | Olivia | 95.5 | A |
| 5 | Sophia | 91.5 | B |
| 6 | Benjamin | 96.5 | A |
| 8 | Michael | 93.5 | B |
| 10 | Ethan | 92 | B |
+----+----------+-------+-------+
6 rows in set
数据分组
在 SQL 查询中,使用 GROUP BY 子句可以对查询结果进行分组。GROUP BY 支持单字段分组和多字段分组。在分组前,可以使用 WHERE 子句对数据进行筛选,可以使用 HAVING 子句在分组后对数据进行筛选,还可以使用 ORDER BY 子句在分组后对数据进行排序。
数据分组注意事项:
- 在使用
GROUP BY子时,SELECT语句中的列必须是GROUP BY子句中的列或聚合函数。 - 在使用
HAVING子句时,HAVING条件是对分组结果进行筛选,而不是对原始数据进行筛选。
单字段分组查询
示例 14:查询表 fruit_order 中每个客户下单数量,并输出 user_id 和 COUNT(order_id)。
SELECT user_id, COUNT(order_id)
FROM fruit_order
GROUP BY user_id;
返回结果如下:
+---------+-----------------+
| user_id | COUNT(order_id) |
+---------+-----------------+
| 1011 | 3 |
| 1022 | 4 |
| 1033 | 2 |
| 1034 | 1 |
+---------+-----------------+
4 rows in set
多字段分组查询
示例 15:查询 fruit_order 中每个客户每年下单数量,并输出 user_id、order_year 和 COUNT(order_id)。
SELECT user_id, order_year, COUNT(order_id)
FROM fruit_order
GROUP BY user_id,order_year;
返回结果如下:
+---------+------------+-----------------+
| user_id | order_year | COUNT(order_id) |
+---------+------------+-----------------+
| 1011 | 2019 | 1 |
| 1011 | 2020 | 2 |
| 1022 | 2019 | 2 |
| 1022 | 2021 | 2 |
| 1033 | 2020 | 1 |
| 1033 | 2021 | 1 |
| 1034 | 2021 | 1 |
+---------+------------+-----------------+
7 rows in set
分组前筛选
示例 16:查询 2020 年每个客户的下单数量,并输出 user_id 和 COUNT(order_id)。
SELECT user_id, COUNT(order_id)
FROM fruit_order t
WHERE t.order_year = 2020
GROUP BY user_id;
返回结果如下:
+---------+-----------------+
| user_id | COUNT(order_id) |
+---------+-----------------+
| 1011 | 2 |
| 1033 | 1 |
+---------+-----------------+
2 rows in set
分组后筛选
当查询中包含 HAVING 时,先获得不含 HAVING 子句时的 SQL 查询结果,然后在这个结果的基础上使用 HAVING 条件筛选出符合的数据,最后返回这些数据。由此,HAVING 后是可以使用聚合函数,并且这个聚集函数不必与 SELECT 后面的聚集函数相同。
示例 17:查询 2019 年订单数量大于 1 的客户,并输出 user_id 和 COUNT(order_id)。
SELECT user_id, COUNT(order_id)
FROM fruit_order t
WHERE t.order_year = 2019
GROUP BY user_id
HAVING COUNT(order_id) >= 2;
返回结果如下:
+---------+-----------------+
| user_id | COUNT(order_id) |
+---------+-----------------+
| 1022 | 2 |
+---------+-----------------+
1 row in set
分组后排序
示例 18:查询每个客户订单的最大金额,然后按照最大金额倒序输出 user_id 和 MAX(fruit_price)。
SELECT user_id, MAX(fruit_price)
FROM fruit_order t
GROUP BY user_id
ORDER BY MAX(fruit_price) DESC;
返回结果如下:
+---------+------------------+
| user_id | MAX(fruit_price) |
+---------+------------------+
| 1033 | 63.66 |
| 1011 | 58.83 |
| 1034 | 53.62 |
| 1022 | 34.44 |
+---------+------------------+
4 rows in set