其他章节:
SQL刷题快速入门(一)
SQL刷题快速入门(二)
承接前两个章节,本系列第三章节主要讲SQL中where和having的作用和区别
、 GROUP BY和ORDER BY作用和区别
、表与表之间的连接操作(重点)
、组合查询
,都是SQL题目中的常考点,日常中也经常使用
where和having的作用和区别
WHERE
和 HAVING
是 SQL 中用于过滤数据的两个不同子句,它们在查询中的作用和用法有所区别。
WHERE 子句
WHERE
子句用于在查询的 FROM
子句之后,对表中的行进行过滤。它可以根据指定的条件来排除不满足条件的行。WHERE
子句可以与 SELECT
, UPDATE
, DELETE
等语句一起使用。
主要特点:
- 用于过滤原始表中的行。
- 不能与聚合函数一起使用。
- 在
GROUP BY
子句之前执行。
示例:
sql
SELECT *
FROM customers
WHERE age > 18;
在这个例子中,WHERE
子句过滤出 customers
表中年龄大于 18 的所有行。
HAVING 子句
HAVING
子句用于在 GROUP BY
子句之后,对分组的结果进行过滤。它通常与聚合函数一起使用,用于指定分组必须满足的条件。HAVING
子句只能与 SELECT
语句一起使用。
主要特点:
- 用于过滤
GROUP BY
后的分组结果。 - 可以与聚合函数一起使用。
- 在
GROUP BY
子句之后执行。
示例:
sql
SELECT category, COUNT(*) AS product_count
FROM products
GROUP BY category
HAVING COUNT(*) > 10;
在这个例子中,GROUP BY
子句按 category
列对 products
表中的行进行分组,并计算每个类别的产品数量。然后 HAVING
子句过滤出产品数量大于 10 的类别。
区别
WHERE
用于过滤原始表中的行,而HAVING
用于过滤分组后的结果。WHERE
不能与聚合函数一起使用,而HAVING
通常与聚合函数一起使用。WHERE
在GROUP BY
子句之前执行,HAVING
在GROUP BY
子句之后执行。- 如果不使用
GROUP BY
子句,则只能使用WHERE
来过滤数据;如果使用GROUP BY
子句,则可以使用HAVING
来对分组后的结果进行进一步的过滤。
在某些情况下,WHERE
和HAVING
可以互换使用,但最佳实践是使用WHERE
来过滤不需要的行,然后使用HAVING
来过滤分组后的结果。
在 SQL 中,WHERE
和 HAVING
子句都用于过滤数据,但它们在查询中执行的位置和用途有所不同。
WHERE
子句用于在聚合操作之前过滤行,它可以与任何类型的 SQL 查询一起使用,包括SELECT
,UPDATE
,DELETE
等。HAVING
子句用于在聚合操作之后过滤分组的结果,它只能与SELECT
语句中的GROUP BY
子句一起使用。
使用 WHERE 子句的情况:
- 当你需要根据单个列或表达式的值来过滤行时,可以使用
WHERE
子句。 - 它可以与
SELECT
,UPDATE
,DELETE
语句一起使用。 - 它可以在聚合操作之前执行,因此它可以用来过滤掉那些不会影响聚合结果的行。
使用 HAVING 子句的情况:
- 当你需要根据聚合函数的结果来过滤分组时,可以使用
HAVING
子句。 - 它只能在包含
GROUP BY
子句的SELECT
语句中使用。 - 它可以在聚合操作之后执行,因此它可以用来过滤掉那些聚合结果不符合特定条件的分组。
示例:
假设你有一个名为 sales
的表,其中包含 product_id
, amount
和 date_sold
列。
如果你想计算每个产品的销售额,并只包括那些销售额大于 100 的产品,你可以使用 WHERE
子句:
sql
SELECT product_id, SUM(amount) AS total_sales
FROM sales
GROUP BY product_id
HAVING SUM(amount) > 100;
在这个查询中,WHERE
子句被省略了,因为它不是必需的。GROUP BY
子句用于分组数据,而 HAVING
子句用于过滤分组后的结果。
如果你想计算每个产品的销售额,并只包括那些销售额大于 100 的产品,你可以使用 WHERE
子句:
sql
SELECT product_id, SUM(amount) AS total_sales
FROM sales
WHERE amount > 100
GROUP BY product_id;
在这个查询中,WHERE
子句用于过滤行,而 GROUP BY
子句用于分组数据。由于 WHERE
子句在聚合操作之前执行,它会影响聚合结果,因此在这种情况下,HAVING
子句不是必需的。
总的来说,WHERE
和 HAVING
子句的主要区别在于它们在查询中的执行顺序和用途。WHERE
子句用于过滤行,而 HAVING
子句用于过滤分组后的结果。在大多数情况下,你只需要使用其中一个,而不是同时使用它们。
GROUP BY和ORDER BY作用和区别
GROUP BY
和 ORDER BY
是 SQL 中两个不同的子句,它们各自有不同的用途和功能:
GROUP BY
GROUP BY
子句用于将查询结果集中的多行数据根据一个或多个列进行分组。它通常与聚合函数(如 COUNT()
, MAX()
, MIN()
, SUM()
, AVG()
等)一起使用,以对每个分组进行计算并返回每个分组的聚合结果。
主要用途:
- 对数据进行分组,以便可以按组别计算数据。
- 必须与聚合函数一起使用,除非数据库支持选择非聚合列(某些数据库,如 MySQL,允许在
GROUP BY
中选择非聚合列,但这通常不被认为是标准 SQL 的最佳实践)。
示例:
sql
SELECT category, COUNT(*) AS product_count
FROM products
GROUP BY category;
在这个例子中,GROUP BY
子句按 category
列对 products
表中的行进行分组,并且计算每个类别的产品数量。
ORDER BY
ORDER BY
子句用于对查询结果集中的数据进行排序。它可以基于一个或多个列进行排序,并且可以指定升序(ASC
)或降序(DESC
)。
主要用途:
- 对查询结果进行排序,以便数据按照特定的顺序显示。
- 不需要与聚合函数一起使用,它可以用于任何查询结果集。
示例:
sql
SELECT *
FROM products
ORDER BY price DESC;
在这个例子中,ORDER BY
子句按 price
列的降序对 products
表中的行进行排序。
区别
GROUP BY
用于对数据进行分组,并通常与聚合函数一起使用,以计算每个分组的统计信息。ORDER BY
用于对查询结果进行排序,无论是否进行了分组。GROUP BY
会影响查询结果的行数(通常行数会减少,因为多行被合并为分组后的单一行),而ORDER BY
不会改变行数,只是改变行的顺序。GROUP BY
可以与HAVING
子句一起使用,以过滤分组后的结果,而ORDER BY
用于在结果被过滤和分组之后进行排序。
在 SQL 查询中,GROUP BY
和ORDER BY
可以同时使用,先分组再排序。例如:
sql
SELECT category, COUNT(*) AS product_count
FROM products
GROUP BY category
ORDER BY product_count DESC;
在这个例子中,首先按 category
列对产品进行分组并计算每个类别的产品数量,然后按产品数量降序排序。
表与表之间的连接操作(重点)
在 SQL 中,表之间的连接操作用于将两个或多个表的数据结合起来,以便可以查询这些表中的数据。连接操作通常用于关联表中的数据,以便可以基于多个表中的数据进行查询。
以下是几种常见的表连接操作:
内连接 (INNER JOIN)
内连接返回两个表中匹配的行。这意味着,只有当两个表中的行满足连接条件时,它们才会出现在查询结果中。
sql
SELECT column1, column2
FROM table1
INNER JOIN table2
ON table1.column_name = table2.column_name;
左连接 (LEFT JOIN)
左连接返回左表(table1)中的所有行,即使在右表(table2)中没有匹配的行。如果右表中没有匹配的行,右表中的列将返回 NULL。
sql
SELECT column1, column2
FROM table1
LEFT JOIN table2
ON table1.column_name = table2.column_name;
右连接 (RIGHT JOIN)
右连接与左连接类似,但返回的是右表(table2)中的所有行,即使在左表(table1)中没有匹配的行。如果左表中没有匹配的行,左表中的列将返回 NULL。
sql
SELECT column1, column2
FROM table1
RIGHT JOIN table2
ON table1.column_name = table2.column_name;
全连接 (FULL JOIN)
全连接返回左表(table1)和右表(table2)中的所有行。如果一个表中没有匹配的行,则使用 NULL 填充。
sql
SELECT column1, column2
FROM table1
FULL JOIN table2
ON table1.column_name = table2.column_name;
自连接 (SELF JOIN)
自连接用于查询一个表中的数据,并将其与同一表中的其他行进行比较。
sql
SELECT table1.column1, table1.column2, table2.column1, table2.column2
FROM table1
INNER JOIN table1 table2
ON table1.common_column = table2.common_column;
交叉连接 (CROSS JOIN)
交叉连接返回两个表中所有可能的组合。
sql
SELECT column1, column2
FROM table1
CROSS JOIN table2;
在选择连接类型时,应考虑实际的数据需求和查询性能。内连接通常是默认连接,除非有特定的理由需要使用其他类型的连接。左连接和右连接通常用于当查询需要包含某些行的数据,即使它们在另一个表中没有匹配的行时。全连接则非常少见,因为它通常会导致大量不必要的数据。自连接用于当需要比较同一表中的数据时。交叉连接则通常用于生成大量的组合数据,但可能会导致性能问题。
组合查询(union连接多个查询语句并去重,带all则不去重)
组合查询,在SQL中通常指的是将两个或多个 SELECT
语句的结果合并成一个结果集的操作。在MySQL中,可以通过 UNION
和 UNION ALL
关键字来实现组合查询。
以下是关于组合查询的一些关键字及其含义:
-
UNION:
UNION
操作符用于合并两个或多个SELECT
语句的结果集,并去除重复的行。- 所有
SELECT
语句中的列数和数据类型必须相同。
示例:
sqlSELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2;
-
UNION ALL:
UNION ALL
操作符与UNION
类似,但是它不会去除重复的行,而是简单地将结果集合并。- 使用
UNION ALL
的查询通常比UNION
快,因为它不需要去重。
示例:
sqlSELECT column_name(s) FROM table1 UNION ALL SELECT column_name(s) FROM table2;
-
ORDER BY:
- 当使用
UNION
或UNION ALL
时,如果需要对最终结果集进行排序,可以在最后一个SELECT
语句后使用ORDER BY
。 ORDER BY
应用于UNION
操作后的整个结果集。
示例:
sqlSELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2 ORDER BY column_name;
- 当使用
-
LIMIT:
- 如果需要对组合查询的结果进行限制,可以在最后一个
SELECT
语句后使用LIMIT
。 LIMIT
通常用于限制返回的行数。
示例:
sqlSELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2 LIMIT 10;
使用组合查询时,需要注意以下几点:
- 如果需要对组合查询的结果进行限制,可以在最后一个
- 每个查询选择的列数必须相同。
- 对应列的数据类型应该兼容。
ORDER BY
子句只能放在最后一个SELECT
语句之后。LIMIT
子句只能放在最后一个SELECT
语句之后,除非是每个单独的查询都有LIMIT
。
组合查询是处理复杂查询需求时的一个强大工具,它可以帮助你从多个数据源中提取和合并数据。