Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 不了解查询如何从每个组检索前n个记录_Sql_Greatest N Per Group - Fatal编程技术网

Sql 不了解查询如何从每个组检索前n个记录

Sql 不了解查询如何从每个组检索前n个记录,sql,greatest-n-per-group,Sql,Greatest N Per Group,我遇到了一个问题,我试图从每个组(每天)或数据库中获取前n个记录。经过一番挖掘,我找到了一些很好的答案,事实上他们解决了我的问题 然而,我的无知使我无法准确理解这些“计数”解决方案的工作原理。如果有更好的SQL知识的人能够解释,那就太好了 编辑:这里有更多的细节 假设我有一个下面描述的表格,其中有这个示例数据。(为了让事情更简单,我有一个专栏记录下一个即将到来的午夜的时间,以便更好地对“每天”进行分组) 每天可能有数十或数百个“人”(b,d,…) id是我分组所需的其他列(如果有帮助的

我遇到了一个问题,我试图从每个组(每天)或数据库中获取前n个记录。经过一番挖掘,我找到了一些很好的答案,事实上他们解决了我的问题

然而,我的无知使我无法准确理解这些“计数”解决方案的工作原理。如果有更好的SQL知识的人能够解释,那就太好了

编辑:这里有更多的细节

假设我有一个下面描述的表格,其中有这个示例数据。(为了让事情更简单,我有一个专栏记录下一个即将到来的午夜的时间,以便更好地对“每天”进行分组)

  • 每天可能有数十或数百个“人”(b,d,…)
  • id是我分组所需的其他列(如果有帮助的话,可以将其视为选举id)
我正在尝试按降序计算每天投票数最高的前5名。我能够使用引用的文章创建一个查询,该查询将给出以下结果(在Oracle上):

所以我不是很确定

  • 为什么这种计算方法有效
  • [愚蠢]:为什么我不需要在内部查询中包含
    name
    ,以确保它不会错误地加入数据

让我们从以下事实开始:您的查询实际上是在计算投票数最低的前五名。要获得数字最高的前5名,您需要更改此条件:

(a.votes_yay+a.votes_nay) >= (b.votes_yay+b.votes_nay)
为此:

(a.votes_yay+a.votes_nay) <= (b.votes_yay+b.votes_nay)
(后一种形式在我看来更可取,但仅仅是因为它与其他两种比较是一致的,这两种比较的左侧有一列
b
,右侧有一列
a
。这与逻辑的正确性完全无关。)

从逻辑上讲,现在发生的事情是这样的。对于
results
中的每一行,服务器将在同一表中查找与给定行的
id
time\u of u midnight
匹配且总投票数与给定行相同或更高的行。然后,它将对找到的行进行计数,并检查结果是否不大于5,即如果同一
(id,午夜时间)
组中不超过5行的投票数与给定行中相同或更高

例如,如果给定的行恰好是其组中投票最多的行,子查询将只找到同一行(假设没有联系),因此计数将为1。这小于5–因此,给定的行符合输出条件


如果给定的行是组中投票数第二多的项目,子查询将找到同一行和投票数最高的项目(同样,假设没有并列关系),这将给出2的计数。同样,这与
计数相匹配。您可以共享您尝试的代码吗?请同时共享表的架构。不太清楚,您在问什么。基本上,在该查询的where子句中,对于目标表的每一行都有一个计数器——例如,该表中有多少行在左侧有更大的ID,以及对右侧行数的限制。所以,从句(…COUNT(*)FROM…)感谢您的深入解释,这绝对有助于我理解它。您知道有没有其他方法可以为每个组提供恰好5个名称,即使第5个名称是并列的?在SQL Server中,我最有可能使用ROW_NUMBER函数。我认为甲骨文也支持它。
   name    | time_of_midnight | votes_yay | votes_nay | total_votes
------------------------------------------------------------------------
 Person s  |         d        |     120   |     63    |     183
 Person p  |         d        |       8   |     10    |      18
 Person r  |         b        |      42   |     22    |      64
 Person p  |         b        |      24   |     36    |      60
 Person q  |         b        |      20   |     10    |      30
(a.votes_yay+a.votes_nay) >= (b.votes_yay+b.votes_nay)
(a.votes_yay+a.votes_nay) <= (b.votes_yay+b.votes_nay)
(b.votes_yay+b.votes_nay) >= (a.votes_yay+a.votes_nay)
SELECT name, time_of_midnight, votes_yay, votes_nay, (votes_yay+votes_nay) AS total_votes
FROM results a
WHERE id=1 AND (
    SELECT COUNT(*) + 1
    FROM results b
    WHERE b.id=a.id AND b.time_of_midnight=a.time_of_midnight
      AND (b.votes_yay+b.votes_nay) > (a.votes_yay+a.votes_nay)) <= 5
ORDER BY time_of_midnight DESC, total_votes DESC;