按两列排序,为啥不先分组呢?

Posted

技术标签:

【中文标题】按两列排序,为啥不先分组呢?【英文标题】:Sort by two columns, why not do grouping first?按两列排序,为什么不先分组呢? 【发布时间】:2018-06-12 10:35:48 【问题描述】:

我有两列,一列是包含客户姓名的字符串字段customer,另一列是代表销售额的数字字段sales

我想做的是按客户对数据进行分组,然后对组内的销售额进行排序。

在 SQL 或 Pandas 中,这通常通过表上的 order by customer, sales 之类的东西来实现。但我只是对这个实现感到好奇。而是先对customer 进行排序,然后对sales 进行排序,为什么不先对customer 进行分组,然后对sales 进行排序。我并不真正关心不同客户的顺序,因为我只关心将相同客户分组在一起的记录。

分组本质上是映射,应该比排序运行得更快。

为什么在 SQL 中没有这样的实现?我错过了什么吗?

示例数据 name,sales john,1 Amy,1 john,2 Amy,3 Amy,4

我希望它按名称分组,然后按销售额排序: name,sales john,1 john,2 Amy,1 Amy,3 Amy,4

在 SQL 中,您可能会使用 select * from table order by name,sales

这绝对可以完成这项工作。但我的困惑是因为我不关心名称的顺序,我应该能够先进行某种分组(这应该比排序便宜)并且只对数字字段进行排序。我能做到吗?为什么谷歌的很多例子只是简单地对这两个字段进行排序?谢谢!

【问题讨论】:

你能提供一个你想要做什么的样本吗? 如果我理解你的要求,我不知道为什么这是不可能的。你应该可以同时使用GROUP BYORDER BY 这可能是一个很好的例子,说明您为什么应该提供您的代码/查询,而不仅仅是一个(开放式)问题。如果你这样做了,你已经有了答案。由于我们只能猜测您的想法,因此我们可以给出的答案是“是的,您可以在同一个查询中订购和分组”。 这里的例子:SQL Group By with an Order By 其实深入研究这个问题,可能是 Pandas 比泛型 SQL 更复杂的情况之一。我对 Pandas 不熟悉,所以它可能比我想象的要容易,但同样,这不是一个非常复杂的操作。按照雅各布的建议,写出你正在尝试做的事情的例子。您也许可以回答您自己的问题。 (如果是这样,请将其发回此处。) 【参考方案1】:

这就是答案-

当您想根据整个组得出结论时,就完成了分组,例如每个组(在本例中为 John 和 Amy)的已完成销售额。它主要与聚合函数一起使用,或者有时仅用于选择不同的记录。你上面写的是按照 name 和 sales 的顺序对数据进行排序,根本不涉及分组。由于该操作是排序的,因此为它编写的命令显然是排序的。

【讨论】:

感谢您的回答。我当然知道排序应该完成这项工作。我只是从计算效率的角度考虑。也许分组不是正确的术语,因为它可能与 groupby 子句混淆。我认为分组类似于映射。对于“名称”相同的记录,可以映射到同一个组,需要O(n)次操作进行扫描,然后在组内排序。如果使用两个排序,第一个排序应该是 O(n log n),具体取决于排序算法,并且应该更慢(尽管它应该具有更好的空间复杂度)。 排序确实给出了分组结果,但组的顺序似乎是多余的信息,不值得额外的复杂性 复杂性完全是一个不同的问题,当你有多种选择来做同样的事情时,它的意义就更大了。在这种情况下,您只有一个选择来实现使用排序的预期结果。因此,如果您排除说明复杂性的可能性,即使您可能是正确的,也不能解决问题。分组的顺序不是多余的,不能排除,因为要将属于同一个集群的对象分组,首先需要对整个数据集进行排序,然后只能比较最近的对象,无论是它的 SQL 还是 Shell脚本 我不知道你为什么说我这里没有多个选项。通过使用任何编程语言中的字典或嵌套列表,可以轻松地扫描所有记录并将它们分配到多个组中。不同组之间的顺序是多余的,因为我不在乎组的名称是否按字母顺序排列。但是对于 SQL,您可能是正确的按两列排序可能是唯一的选择。这正是我问这个问题的原因:如果 group 和 sort 比 sort 两次更有效,为什么 SQL 不包含这个实现。还是因为SQL只关心 空间复杂度和使用那些数据结构会消耗大量内存?还是因为 SQL 具有索引选项,所以可能已经用作分组机制?

以上是关于按两列排序,为啥不先分组呢?的主要内容,如果未能解决你的问题,请参考以下文章

将熊猫数据框按两列分组而不汇总

如何在R中按两列分组

按两列分组,其中一列是时间戳

按两列分组并计算 Pandas 中每个组合的出现次数

按两列分组并获得第三列的最大值

PostgreSQL - 按两列分组并使用一列作为结果列