基础
讲一下distinct的语法
DISTINCT
关键字在 SQL 中用于从结果集中去除重复的行。它可以用于单个字段,也可以用于多个字段。当用于多个字段时,只有当所有指定的字段的组合都相同时,才会被视为重复并去除。
基本语法
单字段去重
SELECT DISTINCT column1
FROM table_name;
这个查询将返回表 table_name
中 column1
字段的唯一值。
多字段去重
SELECT DISTINCT column1, column2
FROM table_name;
这个查询将返回表 table_name
中 column1
和 column2
组合后的唯一值。
示例
假设有一个名为 employees
的表,包含以下数据:
id | first_name | last_name | department |
---|---|---|---|
1 | John | Doe | HR |
2 | Jane | Doe | IT |
3 | John | Smith | IT |
4 | John | Doe | HR |
单字段去重示例
SELECT DISTINCT first_name
FROM employees;
这个查询将返回所有唯一的 first_name
:
first_name |
---|
John |
Jane |
多字段去重示例
SELECT DISTINCT first_name, last_name
FROM employees;
这个查询将返回所有唯一的 first_name
和 last_name
的组合:
first_name | last_name |
---|---|
John | Doe |
Jane | Doe |
John | Smith |
注意事项
DISTINCT
关键字适用于所有字段的组合。如果两个或多个行的所有字段都相同,则这些行被视为重复行。- 当在多个字段上使用
DISTINCT
时,SQL 引擎会根据指定的字段组合来检查重复。 - 在大数据集上使用
DISTINCT
可能会影响性能,因为需要对结果进行去重操作。
DISTINCT
在查询中使用 假设我们有一个查询,需要对多个字段进行去重,并且需要对结果进行排序和限制返回的行数。可以使用如下方式:
SELECT DISTINCT column1, column2
FROM table_name
WHERE some_condition
ORDER BY column1, column2
LIMIT 10;
这个查询将对 column1
和 column2
进行去重,然后按照指定的字段排序,最后限制返回的行数为 10。
limit 语句和distinct哪个先执行
在 SQL 查询的执行过程中,DISTINCT
会先于 LIMIT
执行。这意味着在应用 LIMIT
之前,查询会首先通过 DISTINCT
去除重复的行。
执行顺序
FROM
子句 - 确定从哪个表或视图中选择数据。WHERE
子句 - 应用过滤条件,筛选出满足条件的行。- JOIN 子句 - 执行表的连接操作。
GROUP BY
子句 - 对数据进行分组。HAVING
子句 - 筛选分组后的数据。SELECT
子句 - 选择要返回的列,同时可以包含DISTINCT
去重操作。DISTINCT
操作 - 去除重复的行。ORDER BY
子句 - 对结果集进行排序。LIMIT
子句 - 限制返回的行数。
示例说明
假设有一个名为 employees
的表,包含以下数据:
id | first_name | last_name | department |
---|---|---|---|
1 | John | Doe | HR |
2 | Jane | Doe | IT |
3 | John | Smith | IT |
4 | John | Doe | HR |
查询示例
SELECT DISTINCT first_name, last_name
FROM employees
ORDER BY last_name
LIMIT 2;
执行顺序如下:
FROM 子句 - 读取
employees
表中的所有数据。SELECT 子句 - 选择
first_name
和last_name
列。DISTINCT 操作 - 去除重复的
first_name
和last_name
组合。结果为:first_name last_name John Doe Jane Doe John Smith ORDER BY 子句 - 按
last_name
排序。结果为:first_name last_name John Doe Jane Doe John Smith LIMIT 子句 - 限制返回的行数为 2。最终结果为:
first_name last_name John Doe Jane Doe
总结
在 SQL 查询中,DISTINCT
操作在 LIMIT
之前执行。这意味着查询首先会去除重复的行,然后对去重后的结果集应用 LIMIT
限制返回的行数。
使用SQL判断两表的关联关系
在数据库开发和数据分析中,理解两个表之间的关系是非常重要的。常见的关系类型包括一对一、一对多、多对一和多对多。通过 SQL 查询,我们可以方便地检测和确认这些关系。本文将介绍一个 SQL 查询,它可以帮助我们判断两个表之间的关联关系。
背景
假设我们有两个表 tab_a
和 tab_b
,它们通过一个关联字段(例如 关联id
)进行关联。我们需要确定 tab_a
和 tab_b
之间的关系类型。
查询结构
为了实现这个目标,我们可以使用 SQL 的 WITH
语句(即公用表表达式,CTE)来创建两个子查询,然后根据这些子查询的结果来判断关系类型。
以下是完整的 SQL 查询:
WITH aToMany AS (
SELECT a.id,
COUNT(a.id) AS acount
FROM tab_a a
LEFT JOIN tab_b b ON a.关联id = b.关联id
GROUP BY a.id
HAVING acount > 1
),
bToMany AS (
SELECT b.id AS id,
COUNT(b.id) AS bcount
FROM tab_b b
LEFT JOIN tab_a a ON a.关联id = b.关联id
GROUP BY b.id
HAVING bcount > 1
)
SELECT CASE
WHEN (SELECT COUNT(*) FROM aToMany) = 0 AND (SELECT COUNT(*) FROM bToMany) = 0 THEN 'a比b:一对一'
WHEN (SELECT COUNT(*) FROM aToMany) > 0 AND (SELECT COUNT(*) FROM bToMany) = 0 THEN 'a比b:一对多'
WHEN (SELECT COUNT(*) FROM aToMany) = 0 AND (SELECT COUNT(*) FROM bToMany) > 0 THEN 'a比b:多对一'
WHEN (SELECT COUNT(*) FROM aToMany) > 0 AND (SELECT COUNT(*) FROM bToMany) > 0 THEN 'a比b:多对多'
ELSE '未知关系'
END AS relationship;
优化一下:
WITH aToMany AS (
SELECT a.id,
COUNT(a.id) AS acount
FROM tab_a a
INNER JOIN tab_b b ON a.关联id = b.关联id
GROUP BY a.id
HAVING acount > 1
LIMIT 3
),
bToMany AS (
SELECT b.id AS id,
COUNT(b.id) AS bcount
FROM tab_b b
INNER JOIN tab_a a ON a.关联id = b.关联id
GROUP BY b.id
HAVING bcount > 1
LIMIT 3
)
SELECT CASE
WHEN (SELECT COUNT(*) FROM aToMany) = 0 AND (SELECT COUNT(*) FROM bToMany) = 0 THEN 'a比b:一对一'
WHEN (SELECT COUNT(*) FROM aToMany) > 0 AND (SELECT COUNT(*) FROM bToMany) = 0 THEN 'a比b:一对多'
WHEN (SELECT COUNT(*) FROM aToMany) = 0 AND (SELECT COUNT(*) FROM bToMany) > 0 THEN 'a比b:多对一'
WHEN (SELECT COUNT(*) FROM aToMany) > 0 AND (SELECT COUNT(*) FROM bToMany) > 0 THEN 'a比b:多对多'
ELSE '未知关系'
END AS relationship;
详细解释
aToMany 子查询:
WITH aToMany AS ( SELECT a.id, COUNT(a.id) AS acount FROM tab_a a LEFT JOIN tab_b b ON a.关联id = b.关联id GROUP BY a.id HAVING acount > 1 )
这个子查询计算了
tab_a
中每个id
对应的记录数。如果某个id
对应的记录数大于 1,则说明tab_a
中存在一个对tab_b
的多对一关系。bToMany 子查询:
bToMany AS ( SELECT b.id AS id, COUNT(b.id) AS bcount FROM tab_b b LEFT JOIN tab_a a ON a.关联id = b.关联id GROUP BY b.id HAVING bcount > 1 )
这个子查询计算了
tab_b
中每个id
对应的记录数。如果某个id
对应的记录数大于 1,则说明tab_b
中存在一个对tab_a
的多对一关系。关系判断:
SELECT CASE WHEN (SELECT COUNT(*) FROM aToMany) = 0 AND (SELECT COUNT(*) FROM bToMany) = 0 THEN 'a比b:一对一' WHEN (SELECT COUNT(*) FROM aToMany) > 0 AND (SELECT COUNT(*) FROM bToMany) = 0 THEN 'a比b:一对多' WHEN (SELECT COUNT(*) FROM aToMany) = 0 AND (SELECT COUNT(*) FROM bToMany) > 0 THEN 'a比b:多对一' WHEN (SELECT COUNT(*) FROM aToMany) > 0 AND (SELECT COUNT(*) FROM bToMany) > 0 THEN 'a比b:多对多' ELSE '未知关系' END AS relationship;
最后,我们通过一个
CASE
语句来判断和返回两个表之间的关系。具体判断逻辑如下:- 如果
aToMany
和bToMany
都没有记录,则说明是一对一
关系。 - 如果只有
aToMany
有记录,则说明是一对多
关系。 - 如果只有
bToMany
有记录,则说明是多对一
关系。 - 如果
aToMany
和bToMany
都有记录,则说明是多对多
关系。 - 如果上述情况都不满足,则返回
未知关系
。
- 如果
总结
通过上述 SQL 查询,我们可以清晰地判断两个表之间的关联关系。这个方法利用了公用表表达式(CTE)和聚合函数,使得查询逻辑清晰易懂。希望这篇博客能帮助你更好地理解和使用 SQL 来分析表之间的关系。
使用 Mermaid 语法创建该流程图,流程图的结构将基于您提供的电气行业中组装交流电压大图数据的执行逻辑。以下是 Mermaid 语法的流程图: