在我工作的地方,我最近被告知在查询中使用distinct是程序员的一个不好的标志。所以我想知道我猜唯一不使用这个函数的方法是使用group by。
我的理解是,distinct函数的工作方式与group by非常相似,除了它的读取方式。一个distinct函数检查每个单独的选择标准,而一个group只作为一个整体做同样的事情。
请记住,我只做报告。我不创建/更改数据。因此,我的问题是,最佳做法是我应该使用distinct还是group by。如果两者都没有,那么就没有替代方案。也许group by应该用于比我这里的非真实示例更复杂的查询中,但您可以理解这个想法。我找不到一个答案来真正解释为什么我应该在查询中使用distinct或为什么不应该使用它
select distinct
spriden_user_id as "ID",
spriden_last_name as "last",
spriden_first_name as "first",
spriden_mi_name as "MI",
spraddr_street_line1 as "Street",
spraddr_street_line2 as "Street2",
spraddr_city as "city",
spraddr_stat_code as "State",
spraddr_zip as "zip"
from spriden, spraddr
where spriden_user_id = spraddr_id
and spraddr_mail_type = 'MA'
字符串
VS
select
spriden_user_id as "ID",
spriden_last_name as "last",
spriden_first_name as "first",
spriden_mi_name as "MI",
spraddr_street_line1 as "Street",
spraddr_street_line2 as "Street2",
spraddr_city as "city",
spraddr_stat_code as "State",
spraddr_zip as "zip"
from spriden, spraddr
where spriden_user_id = spraddr_id
and spraddr_mail_type = 'MA'
group by "ID","last","first","MI","Street","Street2","city","State","zip"
型
7条答案
按热度按时间w1e3prcc1#
数据库很聪明,能够识别您的意思。我希望您的两个查询都能同样出色地执行。维护您的查询的其他人知道您的意思是很重要的。如果您真的想检索不同的记录,请使用
DISTINCT
。如果您的意图是进行聚合,请使用GROUP BY
看看this question,有一些不错的答案可能会有所帮助。
toiithl62#
@zedfoxus提供的答案有助于理解上下文。
但是,如果数据设计正确,我认为您的查询不需要不同的记录。
看起来你正在选择表
spriden
的主键,所以所有的数据 * 应该 * 是唯一的。你还加入了spraddr
表;该表真的包含有效的重复数据吗?或者可能需要额外的连接标准来过滤掉这些重复数据?这就是为什么我对使用“
distinct
“感到紧张的原因--spraddr
表可能包含额外的列,您应该使用这些列来过滤数据,而“distinct
“可能隐藏了这些列。此外,您可能会生成一个需要通过“distinct”子句过滤的大量结果集,这可能会导致性能问题。例如,如果
spriden
中的每一行都有100万行,那么您应该使用“is_current”标志来查找2或3个“真实的”行。最后,当我看到“group by”被用作distinct的替代时,我会感到紧张,不是因为它是“错误的”,而是因为从风格上讲,我认为group by应该用于聚合函数。
jdzmm42g3#
在你的例子中,
distinct
和group by
做了同样的事情。我认为你的同事的意思是你的查询不应该在第一个示例中返回重复,你应该能够在没有distinct
或group by
子句的情况下编写查询。你也许可以通过扩展你的join
条件来减少重复。bkkx9g8r4#
问问他们为什么这是一个糟糕的做法。很多人制定规则或提出的东西,他们认为是糟糕的做法从阅读的第一页的书或谷歌搜索的第一个结果。如果它做的工作,并没有造成任何问题,没有理由创造更多的工作,寻找替代品。从两个选项,你已经张贴我会使用distinct太,因为它更短,更容易阅读和维护。“
wgeznvg75#
是的,当我在某人的查询中遇到Distinct时,我的脑海中会产生一点警报。当然,在某些情况下需要它,但大多数数据模型不应该需要它。它往往是不得不使用它的最后手段,或异常情况。它也可能是数据库顶部的一个坏应用程序的系统,允许插入重复条目或将其更新为重复项(同样,没有相应的数据库级别约束来防止此类操作)。因此,首先要检查的是数据。这可能是数据模型设计不好的迹象。但最有可能的是,查询不应该到达选择中重复行停留的阶段。
在构造一个大型查询时,通常我会从指定唯一字段的子查询的块开始,之后的任何子查询都必须内部连接或左连接,但永远不会增加或减少块查询已经定义的行数..并记住处理左连接的可能NULL。
因此,例如,nugget查询也可以通过使用分区来选择正确的行,例如,选择连接表的最近一行,或者在该阶段进行其他分组。
在你的例子中,我不希望重复。如果一个人可以有历史地址,很好,但是你需要看到所有的地址,或者只是最近的,如果有重复的地址,对于同一个人,这是否意味着不正确的重复数据,或者这意味着这个人离开了那个地址,但后来又回到了那个地址.在这种情况下,分区选择将比一个独特的..特别是当字段后来被其他人添加到查询中并打破了独特性时。
这意味着所有其他数据都挂起了这个子查询的金块。你把其他可能的字段粘在核心字段集的右边。
如果Distincts是最后的手段,那么它们通常是为那些已知数据在该表中有重复条目的字段集的情况而保留的,这是完全正常的。在我的脑海中,虽然distincts是一个缓慢的,在计划中的后选择过程,特别是当它返回的是一个大的结果集时。我应该在这些天之内验证一下。
flseospp6#
无论是谁告诉你使用
DISTINCT
是一个坏兆头,这本身就是错误的。实际上,这完全取决于你首先试图使用DISTINCT
解决什么问题。如果您查询的表预期具有某些字段或字段组合的重复值,并且您正在报告值或值组合的列表(并且不对它们执行任何聚合),那么
DISTINCT
是最明智的选择,仅仅因为有人认为DISTINCT
不应该使用,就使用GROUP BY
是没有意义的。事实上,我认为这正是DISTINCT
设计的目的。如果OTOH你发现你的查询有一个bug,这意味着重复的值被返回,你不应该使用
DISTINCT
或GROUP BY
来消除这个bug。相反,你应该找出bug的原因并修复它。使用
DISTINCT
作为安全网也是一种糟糕的做法,因为它可能会隐藏问题,而且它的计算成本很高(通常是O(n log n)或O(n2))。在这种情况下,使用GROUP BY
不会对您有帮助。7cjasjjr7#
如果您的查询是正确的,DISTINCT和GROUP BY提供相同的结果集,但您的同事说DISTINCT隐藏了问题是正确的。如果您缺少连接并使用GROUP BY,您将获得比预期更多的信息。如果您缺少连接并使用DISTINCT,SQL引擎将执行无限的(或部分有界)连接,缩小结果范围,然后得出预期的答案。
除了生成不必要的数据会导致明显的性能下降之外,您还面临着填满临时数据库的风险(即:临时数据库所在的硬盘空间不足)。
在生产中使用GROUP BY。