41

我正在阅读 ms sql 的 RANKING 函数。我了解除 NTILE() 之外的其他功能。假设我有这些数据:

   StudentID     MARKS  
      S1           75  
      S2           83
      S3           91
      S4           83
      S5           93  

所以如果我做一个NTILE(2) OVER(ORDER BY MARKS desc)什么会是结果,为什么?
如果它是一个NTILE(3)?简单的解释任何人?

4

5 回答 5

42

把它想象成桶,NTILE(2) 会产生 2 个桶,一半的行的值为 1,另一半的值为 2

例子

create table  #temp(StudentID char(2),    Marks  int) 
insert #temp  values('S1',75 ) 
insert #temp  values('S2',83)
insert #temp  values('S3',91)
insert #temp  values('S4',83)
insert #temp  values('S5',93 ) 


select NTILE(2) over(order by Marks),*
from #temp
order by Marks

这是输出,因为您的行数是奇数,所以存储桶 1 将多出 1 行

1   S1  75
1   S2  83
1   S4  83
2   S3  91
2   S5  93

如果再添加一行

insert #temp  values('S6',92 ) 

现在两个桶都有 3 行

1   S1  75
1   S2  83
1   S4  83
2   S3  91
2   S6  92
2   S5  93

实际上,我从未在生产代码中使用过 NTILE,但我可以看到您需要将结果拆分为 n 个桶的用途

于 2013-01-16T09:51:23.413 回答
18

它将按照标记的降序排列数据,然后将其分成2组。

如果数据不能被分成相等的组,那么前几组将比后面的组有更多的行。

所以 NTILE(2) 会给你

StudentID       MARKS       NTILE  
      S5           93           1 
      S3           91           1 
      S2           83           1
      S4           83           2
      S1           75           2 

同样 NTILE(3) 会给你

StudentID       MARKS       NTILE  
      S5           93           1 
      S3           91           1 
      S2           83           2
      S4           83           2
      S1           75           3  
于 2013-01-16T09:47:09.447 回答
7

我经常使用 NTILE 将电子邮件列表拆分为存储桶以进行 10/10/80 测试。例如,我们正在测试一封电子邮件的主题行,并希望将两个选项中的一个发送给列表中的每个 10%,将性能更好的一个发送给剩余的 80%。

SELECT [字段列表],(NTILE(10) OVER(order by newid()))-1 AS Segment FROM [数据]

“order by newid()”确保了随机顺序。“[NTILE ...]-1”语法是我们用来进行文本解析而不是整数数学的其他一些工具的直接结果,因此从 0-9 而不是 1-10 运行结果更容易. 细分字段将填充一个 0-9 的值,我可以使用它很容易地分离出 10% 的记录,并且不止一次用于对它们进行多次努力的活动。

如果您需要具有可复制结果的查询,则需要在“order by”子句中使用确定性的内容,或者添加带有 GUID 的列以用于 order by 子句。

PARTITION BY 子句将用于创建基于状态、职业或其他一些预定分组的桶组,即 NTILE(10) OVER (PARTITION BY State ORDER BY newid()) 等。我相信 ORDER BY 子句是必需的 - PARTITION BY 是可选的。

于 2013-12-09T16:12:23.553 回答
0

Ntile 不使用分区子句,只需根据 ntile(number) 中的数字划分数据集,这样:如果行数为 7,例如:1,1,1,2,3,4,5 ntile(3) 将给3,2,2。我是如何得到 3、2、2 的?首先假设 7 为 6(减一以使其相等), 6/3 给出 2,2,2 ,然后添加 +!到第一个分区。如果行数是偶数,那么没有问题。只划分数据集

Ntile 使用分区子句,只需根据数据集中的值划分数据集,这样:如果行数为 7,示例行值为:1,1,1,2,3,4,5 则:ntile(3) 分区按值将给出:1,2,3,1,1,1,1。我是怎么得到这个的?首先根据值分解数据集:这里,1,1,1 是一个分区,接下来所有值形成一个不同的分区。然后开始为每个分区分配 ntile rank。在这里,1,1,1 将变为 1,2,3 然后继续下一个分区,您只能将排名拉到 ntile() 函数中指定的数字

于 2015-04-09T06:17:03.353 回答
0

在 Ntile 函数中,首先计算行数并除以 ntile 传入的参数,然后根据商组成相等的一组行并对其进行排序,然后将剩余的行从顶部以移动方式分配给每个组并且不会从最少的行中取出它,例如如果 group1 有 4 行,那么它将在其组中占据第 5 行而不是最后一行。

谢谢

于 2015-02-12T08:30:47.863 回答