在 SQL 中查找唯一记录的 3 种终极方法

停止使用 DISTINCT!开始使用这些快速替代方案以避免混淆! — 无需使用 DISTINCT 关键字即可获得唯一记录! 🏆 在您的数据分析项目中,每当您需要从数据库中提取唯一记录时,一个简单的答案就是使用 DISTINCT!毫无疑问,DISTINCT 是为返回唯一的行而设计的,它的工作做得很好。但是,它不…

Data Science

在 SQL 中查找唯一记录的 3 种终极方法

停止使用 DISTINCT!开始使用这些快速替代方案以避免混淆!

在 SQL 中查找唯一记录的 3 种终极方法

无需使用 DISTINCT 关键字即可获得唯一记录! 🏆

在您的数据分析项目中,每当您需要从数据库中提取唯一记录时,一个简单的答案就是使用 DISTINCT!

毫无疑问,DISTINCT 是为返回唯一的行而设计的,它的工作做得很好。但是,它不会告诉您您使用的 JOIN 和过滤器是正确还是不正确,这实际上是导致重复的原因。

因此,我总结了 3 种最佳、安全且省时的替代方案,它们在 DISTINCT 处返回相同的输出,并且仍然保持代码干净且易于维护。 💯

您可以使用以下索引跳转到您最喜欢的部分。

· UNION()
·
INTERSECT()
·
ROW_NUMBER()
·
GROUP BY

📍 注意:我使用的是 SQLite DB 浏览器和一个自行创建的 Dummy_Employees,你可以在我的 Github 存储库上免费获得它![0][1]

好的,我们开始……🚀

首先,让我向您展示数据的样子。

在 SQL 中查找唯一记录的 3 种终极方法

这是一个简单的 10×4 数据集,我在我的文章 Faker: An Amazing and Insanely Useful Python Library 中创建了它。 📚[0]

上图中以蓝色和红色突出显示的行在数据集中重复。

📚 您可以使用此 SQLite 数据库来跟踪本文中的查询。[0]

正如我在上一篇文章《2022 年你应该知道的 5 个实用 SQL 查询》中提到的,在寻找唯一记​​录之前,你必须定义哪些列或组合列构成唯一行。[0]

对于在单个列中查找唯一值,DISTINCT 总是更方便。但是,为了从数据集中检索唯一的行,这些替代方案可以保持代码的清洁和高效。

例如,让我们使用 DISTINCT 从数据集中获取employee_id、employee_name 和department 的唯一组合。

SELECT DISTINCT employee_id,
employee_name,
department
FROM Dummy_employees
在 SQL 中查找唯一记录的 3 种终极方法

正如预期的那样,它只返回一次属于employee_id 102 和212 的重复行,最终产生8 行。

现在,让我们看看如何在不单独使用 DISTINCT 的情况下获得完全相同的结果。

UNION()

在 SQL 中,UNION 是一个运算符,用于组合两个 SELECT 语句的结果。它类似于集合上的 UNION 操作。

此外,它会删除结果数据集中多次出现的行,并仅保留每行的一次出现。 ✅

您只需编写两个完全相同的 SELECT 语句并将它们与运算符 UNION 连接起来,如下所示。

SELECT employee_id,
employee_name,
department
FROM Dummy_employees
UNIONSELECT employee_id,
employee_name,
department
FROM Dummy_employees
在 SQL 中查找唯一记录的 3 种终极方法

这显示了与 DISTINCT 相同的输出,只是记录的顺序不同。

现在,让我向您展示刚刚在后端发生的事情。🛠️

在 SQL 中查找唯一记录的 3 种终极方法

通过这种方式,UNION 只需连接两个单独的 SELECT 语句的输出,并仅保留重复行的一次出现。

选择唯一记录的下一个有趣方法是使用另一个运算符 – INTERSECT。

INTERSECT()

与前面的运算符类似,INTERSECT 也用于连接两个 SELECT 查询的结果,并且只返回在两个 SELECT 查询的输出中共有的记录。与两组的交集相同。

INTERSECT 还会删除结果数据集中多次出现的行,并仅保留每行的一次出现。 ✅

您只需编写两个完全相同的 SELECT 语句并将它们与 INTERSECT 连接起来,如下所示。

SELECT employee_id,
employee_name,
department
FROM Dummy_employees
INTERSECTSELECT employee_id,
employee_name,
department
FROM Dummy_employees
在 SQL 中查找唯一记录的 3 种终极方法

由于两个 SELECT 查询都产生相同的输出,因此连接将产生 10 行数据。然后通过INTERSECTs返回唯一行的固有属性,只会返回一次重复行,最终输出8行。

🚩 注意:在使用 UNION 和 INTERSECT 时,两个 SELECT 语句中的列数和顺序必须相同。

继续下一个获取独特记录的方法。

ROW_NUMBER()

在 SQL 中,ROW_NUMBER() 是一个窗口函数,用于为结果集分区内的每一行分配一个顺序整数。

窗口函数:一种 SQL 函数,其中输入值取自 SELECT 语句结果集中的一个或多个行的“窗口”。这使用 OVER 子句后跟 PARTITION BY 和 ORDER BY 子句来创建一个或多个行的窗口。

因此,在每个分区中,行号 1 分配给第一行。✅

下面是它的工作原理..

SELECT employee_id,
employee_name,
department,
ROW_NUMBER() OVER(PARTITION BY employee_name,
department,
employee_id) as row_count

FROM Dummy_employees
在 SQL 中查找唯一记录的 3 种终极方法

如您所见,当employee_name 为Abdul 和Stella 时,每个分区中有两行。因此,行号 2 被分配给这些重复行中的每一个。

因此,要获得唯一记录,您需要选择行号为 1 的所有行,即上表中 row_count 的值为 1。

❓ 但是,这里有个问题!!

不能在 WHERE 子句中使用窗口函数,因为在 SQL 查询执行中,在计算窗口函数之前会处理 WHERE 子句。您可以在 Agnieszka 的这篇文章中阅读有关 SQL 查询执行顺序的更多信息。[0]

最终,您需要创建一个临时表来存储上述查询的输出,并且需要另一个 SELECT 语句来获取不同的记录。您可以使用 WITH 子句或 CTE(通用表表达式)来创建临时表。 💯

让我们看看如何使用它从数据集中获取employee_id、employee_name 和department 的唯一组合。

WITH temporary_employees as
(
SELECT
employee_id,
employee_name,
department,
ROW_NUMBER() OVER(PARTITION BY employee_name,
department,
employee_id) as row_count

FROM Dummy_employees
)
SELECT *
FROM temporary_employees
WHERE row_count = 1
在 SQL 中查找唯一记录的 3 种终极方法

通过这种方式,您可以看到只有那些记录出现在输出中 row_count = 1

在这里,最后一列 — row_count 仅用于提供信息。即使您不包括此列,查询仍然有效。

除了运算符和窗口函数之外,还有一种简单方便的方法来获取唯一的行——GROUP BY

GROUP BY

在 SQL 中,GROUP BY 子句用于按一列或多列对行进行分组。它通常与 COUNT()、MAX()、MIN()、SUM()、AVG() 等聚合函数一起使用,以获取分组行的聚合计算。

但是,它可以在没有任何聚合函数的情况下使用来获得不同或唯一的记录,如下所示,

SELECT employee_id,
employee_name,
department
FROM Dummy_employees
GROUP BY employee_id,
employee_name,
department
在 SQL 中查找唯一记录的 3 种终极方法

简单地说,您需要在 GROUP BY 子句中提及所有列名以获取唯一记录。

几乎 90% 的时间,我发现 GROUP BY 更方便,因为我一直想使用聚合函数进行一些其他计算。

That’s all!

我希望你能快速完成这篇文章,并发现它令人耳目一新且有用。

我从过去 3 年开始使用 SQL,我发现这些替代方案非常节省时间,而且功能强大,尤其是在处理大型数据集时。此外,我发现其中一些问题是很好的面试问题。

有兴趣在 Medium 上阅读无限的故事吗?

💡考虑成为媒体会员以访问媒体和每日有趣的媒体摘要上的无限故事。我会得到你的一小部分费用,并且不会给你额外的费用。[0]

💡 不要忘记注册我的电子邮件列表以接收我的文章的第一份副本。[0]

感谢您的阅读!

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
乘风的头像乘风管理团队
上一篇 2022年6月14日 下午12:35
下一篇 2022年6月14日 下午12:43

相关推荐