1. DQL简介
DQL(Data Query Language)是数据库查询语言,它是SQL(Structured Query Language,结构化查询语言)的一个子集,专门用于从数据库中检索数据。
以下是常见的DQL语句和其功能:
SELECT:用于从数据库中查询数据。
例:SELECT column1, column2 FROM mytable WHERE condition;
FROM:指定要查询的数据表。
例:SELECT column1, column2 FROM mytable;
WHERE:指定查询过滤条件。
例:SELECT column1, column2 FROM mytable WHERE condition;
GROUP BY:按照指定的列对查询结果进行分组。
例:SELECT column1, COUNT(column2) FROM mytable GROUP BY column1;
HAVING:指定对分组后的结果进行过滤的条件。
例:SELECT column1, COUNT(column2) FROM mytable GROUP BY column1 HAVING COUNT(column2) > 10;
ORDER BY:指定查询结果的排序顺序。
例:SELECT column1, column2 FROM mytable ORDER BY column1 ASC;
JOIN:用于将多个表按照某些条件连接在一起进行查询。
例:SELECT t1.column1, t2.column2 FROM table1 t1 JOIN table2 t2 ON t1.id = t2.id;
注意1:除了SELECT语句,DQL还可以包括其他一些语句,如子查询语句(将一个查询结果作为另一个查询的输入)、WITH语句(定义可重用的查询块)、UNION操作(将多个查询结果合并)等。
2. select查询
SELECT是SQL语言中用于从数据库中检索数据的关键字。
它是最常用的SQL操作之一,用于查询数据库表中的数据并返回结果集。
SELECT语句的基本语法如下:
SELECT [distinct]*|列名1, 列名2, ... FROM 表名 WHERE 条件 GROUP BY 列名 HAVING 条件 ORDER BY 列名 [ASC|DESC]
SELECT语句的解释如下:
DISTINCT关键字放在SELECT后面的列名之前,用于指示去除重复的记录。
*表示选择所有列,相当于列出了表中的所有列名。
列名:指定要检索的列名。可以使用*来表示检索表中的所有列,也可以指定单个或多个列名。
FROM子句:指定要从中检索数据的表名。
WHERE子句(可选):用于指定数据行的选择条件。只有满足条件的行才会包含在结果集中。
GROUP BY子句(可选):用于将结果集按指定列进行分组,通常与聚合函数(如SUM、COUNT等)一起使用。
HAVING子句(可选):用于对分组后的结果集进行过滤,条件表达式用于指定哪些分组结果将包含在结果集中。
ORDER BY子句(可选):用于按指定列对结果集进行排序。默认情况下,按升序(ASC)排序,可以指定DESC来进行降序排序。
简单查询:
SELECT 列名1, 列名2, ... FROM 表名
3. 条件查询
3.1 条件查询简介
条件查询是指在SELECT语句中使用WHERE子句来过滤出满足特定条件的数据。
它允许根据指定的条件从数据库表中提取出符合条件的数据。
基本语法如下:
SELECT 列名1, 列名2, ... FROM 表名 WHERE 条件;
说明:
列名1、列名2表示需要检索的列名,可以选择性地指定需要的列,也可以使用 * 来表示检索所有列。
表名表示要从中检索数据的表名。WHERE子句用于指定过滤条件,只有满足条件的行才会包含在结果集中。
在WHERE子句中可以使用各种比较运算符(例如等号、大于、小于、大于等于、小于等于等)、逻辑运算符(如AND、OR和NOT)等来构建条件。
通过在WHERE子句中指定适当的条件,可以对数据库中的数据进行灵活的过滤和查询。
条件查询是在实际应用中经常使用的查询方式,它提供了一种方便的方法来限定要检索的数据范围。
条件查询分为以下几类:
3.2 比较查询
比较查询是数据库中使用比较运算符进行条件筛选的一种查询方式。
它可以用于比较表中的字段与给定值之间的关系,然后返回满足条件的数据。
常用的比较运算符有以下几种:
于(=):检查两个值是否相等。
不等于(<>或!=):检查两个值是否不相等。
大于(>):检查左边的值是否大于右边的值。
大于等于(>=):检查左边的值是否大于或等于右边的值。
小于(<):检查左边的值是否小于右边的值。
小于等于(<=):检查左边的值是否小于或等于右边的值。
比较查询的语法可以根据具体的数据库系统而有所不同,但通常的基本语法如下:
SELECT 列名 FROM 表名 WHERE 列名 运算符 值;
说明:列名代表要比较的字段,运算符代表要使用的比较运算符,值代表要进行比较的值。
3.3 非空查询
非空查询用于在数据库中查找非空(不为NULL)的值。
在进行非空查询时,我们可以使用IS NOT NULL
运算符来筛选出非空值。
非空查询的语法如下:
SELECT * FROM table_name WHERE column_name IS NOT NULL;
说明:
table_name是要查询的表名,column_name是要检查非空的列名。
执行非空查询时,该语句将返回指定表中指定列中非空的记录。
非空查询的作用是能够排除包含NULL值的记录,只获取有意义和实际存在的数据。在数据库中,NULL表示一个缺失、未知或不适用的值,而非空查询则可以帮助我们过滤掉这些无效或不适用的数据。
在进行非空查询时,需要注意以下几点:
确保所查询的列允许为NULL,如果该列定义为NOT NULL,则该列不可能包含NULL值,非空查询将不会返回任何记录。
注意区分NULL值和空字符串。NULL表示未知或未提供值,而空字符串表示有一个值,但该值是空的。非空查询只能排除NULL值,如果还希望排除空字符串,可以使用额外的条件进行筛选。
总结来说,非空查询是一种常用的数据库查询方式,用于筛选出不包含NULL值的记录,以获取真实的和有意义的数据。在处理数据时,非空查询可以提高查询结果的准确性和可靠性。
3.4 范围查询
范围查询是一种常用的数据库查询方式,它可以用来筛选出满足指定范围条件的数据。
(1)使用BETWEEN AND进行范围查询:
语法格式:
字段名 BETWEEN value1 AND value2
示例:
SELECT * FROM table_name WHERE column_name BETWEEN value1 AND value2;
描述:BETWEEN AND运算符用于指定某个列中的值在给定范围内的条件。范围包含了value1和value2两个边界值。
(2)使用IN进行范围查询:
语法:
column_name IN (value1, value2, ...)
示例:
SELECT * FROM table_name WHERE column_name IN (value1, value2, ...);
描述:IN运算符允许指定某个列中值的一个列表,只要列中的值与列表中的任何一个值匹配,就会被包含在查询结果中。
这两种范围查询方式的主要区别在于传递给它们的参数类型和数量。
BETWEEN AND适用于连续的范围条件,可以用于数值、日期等类型的列。它包括了边界值。
IN适用于离散的范围条件,可以使用多个值进行指定。它可以用于任意数据类型的列,例如字符型、数值型、日期型等。
范围查询常用于筛选指定范围内的数据,例如查询某个时间段内的订单、筛选指定数值范围内的商品价格等。
使用范围查询可以提高查询效率和准确性,同时可以降低查询的复杂度。
3.5 模糊查询
模糊查询(Like查询)是一种在数据库中使用模式匹配进行条件筛选的查询方式,可以根据指定的模式匹配规则搜索满足条件的数据。
Like查询使用通配符来匹配模式,其中常用的通配符是百分号(%
)和下划线(_
),以实现更灵活的模式匹配。
(1)百分号(%)通配符:代表零个或多个字符。可以用在模式的任意位置。
示例:
SELECT * FROM table_name WHERE column_name LIKE '%abc%';
描述:该查询会匹配任何包含"abc"的值,如"abc123"、"123abc"、"abcdef"等。
(2)下划线( _)通配符:代表一个单个字符。可以用在模式的任意位置。
示例:
SELECT * FROM table_name WHERE column_name LIKE 'a_';
描述:该查询会匹配以"a"开头,并且后面跟着任何一个字符的值,如"ab"、"ax"、"az"等。
3.6 逻辑查询
逻辑查询是基于逻辑运算符(例如AND、OR、NOT)和条件表达式的一种查询方式,用于从数据库中检索满足指定条件的数据。
在SQL中,逻辑查询通常使用SELECT语句结合WHERE子句来实现。WHERE子句可以包含多个条件表达式,并且通过逻辑运算符组合这些条件来构建复杂的查询条件。
以下是几个常用的逻辑运算符:
(1)AND运算符:用于指定多个条件同时满足的查询。
示例:
SELECT * FROM table_name WHERE condition1 AND condition2;
描述:该查询会返回满足condition1和condition2的记录。
(2)OR运算符:用于指定多个条件中任何一个满足的查询。
示例:
SELECT * FROM table_name WHERE condition1 OR condition2;
描述:该查询会返回满足condition1或condition2的记录。
(3)NOT运算符:用于指定条件的否定查询。
示例:
SELECT * FROM table_name WHERE NOT condition;
描述:该查询会返回不满足condition的记录。
逻辑查询可以根据具体需求对条件进行组合和嵌套,以实现更复杂的查询逻辑。
4. 排序查询
排序查询是通过SQL语句对数据库中的数据进行排序的查询操作。
它可以根据一个或多个字段对查询结果进行排序,以便更好地理解和分析数据。
语法格式:
SELECT 列名1, 列名2, ... FROM table ORDER BY 列名1 [ASC|DESC], 列名2 [ASC|DESC], ...;
说明:
[ASC|DESC]
:可选参数,用于指定排序的方式,ASC
表示升序(默认),DESC
表示降序。可以将单个字段或多个字段用逗号隔开,并分别指定排序方式。
默认情况下,如果没有指定排序方式,默认为升序排序。
在使用多个字段进行排序时,首先会根据第一个字段进行排序,如果有相同的值,再按照第二个字段进行排序,依此类推。
SQL语句执行顺序:首先执行
SELECT
语句获取结果集,然后根据ORDER BY
子句对结果集进行排序。
5. 聚合查询
之前我们做的查询都是横向查询,它们都是根据条件一行一行的进行判断。
而使用聚合函数查询是纵向查询,它是对一列的值进行计算,然后返回一个单一的值;
另外聚合函数会忽略空值。
聚合查询是一种用于对数据库中的数据进行统计和计算的查询操作,通常结合使用聚合函数。
聚合查询用于对数据进行统计和计算,而不是简单的返回原始数据。
通过聚合查询,可以计算数据的总和、平均值、最大值、最小值、数量等。
基本语法格式:
SELECT aggregate_function(column1), aggregate_function(column2), ... FROM table WHERE condition GROUP BY column1, column2, ... HAVING condition;
说明:
SELECT
:指定要返回的聚合结果。aggregate_function
:聚合函数,用于计算数据的统计值。FROM
:指定要查询的表名。WHERE
:可选项,添加查询条件对数据进行筛选。GROUP BY
:指定按照哪些字段进行分组。HAVING
:可选项,对分组后的数据进行筛选。常用聚合函数:
聚合函数 | 作用 |
---|---|
COUNT(column) | 统计某一列的非空值数量。 |
SUM(column) | 计算某一列的数据之和,如果指定列类型不是数值类型,则计算结果为0。 |
MAX(column) | 找出某一列中的最大值,如果指定列是字符串类型,使用字符串排序运算。 |
MIN(column) | 找出某一列中的最小值,如果指定列是字符串类型,使用字符串排序运算。 |
AVG(column) | 计算某一列的数据平均值,如果指定列类型不是数值类型,则计算结果为0。 |
6. 分组查询与having子句
6.1 分组查询简介
分组查询是一种用于对数据库中的数据进行分组和聚合的查询操作。通过分组查询,可以按照指定的字段进行分组,并对每个组进行聚合计算。
分组查询用于将数据库中的数据按照指定的字段进
SELECT column1, column2, ..., aggregate_function(column) FROM table WHERE condition GROUP BY column1, column2, ... HAVING condition;
行分组,并对每个组进行聚合计算。通过分组查询,可以实现对数据的分组统计。
GROUP BY
语句用于将结果按照一个或多个列进行分组,然后对每个组进行聚合运算。
在分组查询中,除了使用GROUP BY
对数据进行分组外,还可以使用HAVING
子句来对分组后的数据进行筛选。HAVING
子句用于筛选满足特定条件的分组结果。
HAVING
子句在分组查询中起到了类似于WHERE
子句的作用,但是WHERE
子句过滤的是行级数据,而HAVING
子句过滤的是分组后的结果。
语法格式:
SELECT column1, column2, ..., aggregate_function(column) FROM table WHERE condition GROUP BY column1, column2, ... HAVING condition;
SELECT
:指定要查询的字段,可以包括普通字段和聚合函数。column1, column2, ...
:要查询的字段,可以是单个字段或多个字段。aggregate_function(column)
:指定要进行聚合计算的字段。FROM
:指定要查询的表名。WHERE
:可选项,添加查询条件对数据进行筛选。GROUP BY
:指定按照哪些字段进行分组。分组计算:在分组查询中,可以使用各种聚合函数对每个组的数据进行计算,常用的聚合函数有:
SUM
、AVG
、COUNT
、MAX
、MIN
等。注意事项:需要注意的是,在分组查询中,除了聚合函数计算的字段外,其他字段必须出现在
GROUP BY
语句中。例如,如果查询SELECT column1, AVG(column2) FROM table GROUP BY column1;
,则column1
必须出现在GROUP BY
语句中。HAVING
:可选项,对分组结果进行筛选。
6.2 group by的使用
例:
-- 根据gender字段来分组 select gender from students group by gender; -- 根据name和gender字段进行分组 select name, gender from students group by name, gender;
说明:
group by可以实现去重操作
group by的作用是为了实现分组统计(group by + 聚合函数)
6.3 group by + 聚合函数的使用
例:以下示例将列出每个部门的员工数量和平均工资
SELECT department_id, COUNT(*) AS employee_count, AVG(salary) AS average_salary FROM employees GROUP BY department_id;
说明:
通过在
GROUP BY
语句中指定department_id
字段,将结果按照部门进行分组。然后使用
COUNT(*)
函数计算每个组的员工数量,并使用AVG(salary)
函数计算每个组的平均工资。注意事项:
在
SELECT
子句中,除了聚合函数外,所查询的字段必须是分组字段或存在于GROUP BY
子句中,否则将产生错误。分组字段的顺序不影响结果,但可以根据需要指定多个分组字段。
6.4 group by + having的使用
HAVING
子句在分组查询中起到了类似于WHERE
子句的作用,但是WHERE
子句过滤的是行级数据,而HAVING
子句过滤的是分组后的结果。
所以,having
是过滤分组数据的,只能用于group by
。
HAVING
子句用于对分组后的结果进行筛选。它可以包含聚合函数、分组字段和其他条件表达式。
案例1:
-- 根据gender字段进行分组,统计分组条数大于2的 select gender,count(*) from students group by gender having count(*)>2;
案例2:
#1 统计各个分类商品的个数 SELECT category_id ,COUNT(*) FROM product GROUP BY category_id ; #2 统计各个分类商品的个数,且只显示个数大于1的信息 SELECT category_id ,COUNT(*) FROM product GROUP BY category_id HAVING COUNT(*) > 1;
案例3:求每个客户的订单总金额大于1000的客户
SELECT customer_id, SUM(order_amount) AS total_amount FROM orders GROUP BY customer_id HAVING SUM(order_amount) > 1000;
案例4:求每个部门的平均工资大于5000的部门
SELECT department_id, AVG(salary) AS avg_salary FROM employees GROUP BY department_id HAVING AVG(salary) > 5000;
说明:
使用
HAVING
子句对分组后的结果进行筛选,只返回满足条件的分组结果。通过使用
HAVING
子句,可以在分组查询中进一步筛选满足特定条件的分组结果。这使得分组查询更加灵活和强大。
7. limit分页查询
LIMIT
关键字用于分页查询,它限制了查询结果返回的记录数,从而实现数据的分页显示。
LIMIT
语法可以在SELECT
语句中使用,具体格式如下:
SELECT column1, column2, ... FROM table LIMIT offset, count;
column1, column2, ...
:要查询的字段,可以是单个字段或多个字段。table
:要查询数据的表名。offset
:结果集的起始位置,表示返回结果时忽略前面的多少条记录。(起始位置从0开始)count
:要返回的记录数,指定返回多少条记录。
案例:使用LIMIT
语句进行分页查询
SELECT * FROM customers LIMIT 10, 5;
说明:
查询结果将从第11条记录开始(起始位置为10),返回5条记录。这表示查询结果是从第11条记录到第15条记录。
分页查询的常见使用场景是实现网页或移动应用的分页显示功能。通过在每次查询中适当设置
offset
和count
的值,可以实现分页显示不同页的数据。要注意的是,
LIMIT
语句的效果取决于数据库的排序方式。因此,在进行分页查询之前,最好在SELECT
语句中使用ORDER BY
子句对结果进行排序,以确保分页结果的准确性和一致性。
在处理大量数据时,还可以使用LIMIT
语句进行优化,根据需求逐步加载页面数据并减少数据库的压力。
8. 连接查询
8.1 连接查询的介绍
连接查询(Join)是在关系型数据库中用于将多个表中相关联的数据进行关联的一种查询操作。它基于表之间的关联关系,通过共享的列(也称为关联列或连接列)将多个表中的数据进行匹配和组合。
连接查询可以根据表之间的关联条件,将满足条件的数据行进行合并,生成一个包含了来自多个表的相关数据的结果集。连接查询的结果可以包含来自一个表或多个表的列数据,根据关联条件对数据行进行匹配和组合。
在SQL中,连接查询通常使用JOIN
关键字来指定连接的表以及关联条件。
常见的连接类型包括:
内连接(Inner Join):返回两个表中满足关联条件的数据行。
左连接(Left Join):返回左表中的所有数据行以及满足关联条件的右表中的数据行。
右连接(Right Join):返回右表中的所有数据行以及满足关联条件的左表中的数据行。
全外连接(Full Outer Join):返回满足关联条件的两个表中的所有数据行。
8.2 内连接查询
内连接(Inner Join)是连接查询中最常用的一种连接类型。它通过关联两个表的列,将满足关联条件的数据行进行合并,生成一个包含了来自多个表的相关数据的结果集。
内连接查询返回的结果集只包含两个表中满足关联条件的数据行。
具体来说,对于两个表A和B,内连接查询会根据给定的关联条件,将表A和表B中符合条件的数据行进行匹配和组合。只有在两个表中都存在匹配的数据行时,才会将这些数据行包含在结果集中。
在SQL中,内连接查询通常使用INNER JOIN
关键字来指定连接的表以及关联条件。
内连接查询的特点和应用场景包括:
内连接只返回满足关联条件的数据行,因此结果集中会排除那些不满足关联条件的数据行。
内连接可以基于一个或多个关联条件进行查询,关联条件可以使用等号、不等号、比较运算符等。
内连接可以连接两个以上的表,将多个表中的数据进行关联。
内连接可以对多个表中的列进行筛选、聚合和排序等数据操作。
内连接可以用于查询多表关联和数据分析等场景,提供了灵活和高效的数据检索和分析手段。
需要注意的是,内连接只返回满足关联条件的数据行,因此在实际应用中,需确保关联条件的准确性和合理性,以避免获取不完整或错误的数据。
内连接查询的语法格式:
SELECT 列列表 FROM 表A INNER JOIN 表B ON 关联条件;
说明:
通过
INNER JOIN
关键字将表A和表B连接起来。并通过
ON
子句指定了关联条件,该条件用于匹配和组合两个表中的数据行。
8.3 左外连接查询
左外连接(Left Outer Join)是连接查询中的一种连接类型,它基于左表的所有数据行,将满足关联条件的右表数据行合并到结果集中。
如果右表中没有符合关联条件的数据行,则会在结果集中用 NULL 值表示。
左外连接查询的语法格式如下:
SELECT 列列表 FROM 表A LEFT JOIN 表B ON 关联条件;
说明:
通过
LEFT JOIN
关键字将表A和表B进行连接。通过
ON
子句指定了关联条件,该条件用于匹配和组合两个表中的数据行。
8.4 右外连接查询
右外连接(Right Outer Join)是连接查询中的一种连接类型,它基于右表的所有数据行,将满足关联条件的左表数据行合并到结果集中。如果左表中没有符合关联条件的数据行,则会在结果集中用 NULL 值表示。
右外连接查询的语法格式如下:
SELECT 列列表 FROM 表A RIGHT JOIN 表B ON 关联条件;
说明:
通过
RIGHT JOIN
关键字将表A和表B进行连接通过
ON
子句指定了关联条件,该条件用于匹配和组合两个表中的数据行。
8.5 全外连接查询
SELECT 列列表 FROM 表A FULL JOIN 表B ON 关联条件;
全外连接(Full Outer Join)是连接查询中的一种连接类型,它基于两个表的所有数据行,将满足关联条件的数据行合并到结果集中。
如果一个表中没有符合关联条件的数据行,则会在结果集中用 NULL 值表示。
全外连接查询的语法格式如下:
SELECT 列列表 FROM 表A FULL JOIN 表B ON 关联条件;
说明:
通过
FULL JOIN
关键字将表A和表B进行连接。通过
ON
子句指定了关联条件,该条件用于匹配和组合两个表中的数据行。需要注意的是,不同的数据库管理系统(如MySQL、SQL Server)对全外连接的语法支持有所差异。在某些数据库管理系统中,可以使用
OUTER
关键字来表示全外连接。
9. 子查询
子查询(Subquery)是指在一个查询语句中嵌套使用的查询。
它可以在主查询中使用一个或多个嵌套的子查询作为条件、表达式或子查询结果集。
子查询可以提供更具体和复杂的查询逻辑,允许我们在查询中使用动态的、基于其他查询结果的值。
子查询的语法格式如下:
SELECT 列列表 FROM 表 WHERE 列 IN (SELECT 列列表 FROM 表 WHERE 条件);
说明:
WHERE 列 IN
:使用子查询结果作为主查询中的筛选条件,列表示主查询中的列名。(SELECT 列列表 FROM 表 WHERE 条件)
:子查询的语法,它会返回一个结果集作为主查询的筛选条件。子查询中可以使用自己的表和条件,也可以使用父查询的表和条件。在上述语法中,子查询被包括在括号内,作为主查询的条件之一或子查询结果集被用于参与主查询的其他部分。
子查询可以返回单个值、单列值列表或多列值列表,具体取决于子查询的目的和位置。
主查询和子查询的关系:
子查询是嵌入到主查询中。
子查询是辅助主查询的,要么充当条件,要么充当数据源(数据表)。
子查询是可以独立存在的语句是一条完整的 select 语句。
以下是一些常见的子查询应用场景:
(1)使用子查询作为主查询的条件:子查询返回一个值(标量子查询),可以用于比较、过滤或计算主查询中的条件。
SELECT 列列表 FROM 表 WHERE 列 = (SELECT 列 FROM 表 WHERE 条件);
(2)使用子查询作为主查询的列值:子查询返回一个列(列子查询),可以作为主查询中的一个列值进行显示。
SELECT 列, (SELECT 列 FROM 表 WHERE 条件) AS 列名 FROM 表;
(3)使用子查询作为主查询的表:子查询返回一个结果集,可以用作主查询中的一个表。
SELECT 列列表 FROM (SELECT 列列表 FROM 表 WHERE 条件) AS 子查询表 JOIN 表 ON 子查询表.列 = 表.列;
子查询可以根据实际需要嵌套多层,形成复杂的查询逻辑。它提供了更高级和灵活的查询能力,可以根据查询结果进行动态的条件控制和数据处理。