Sql 想了解更多有关NTILE()的信息

Sql 想了解更多有关NTILE()的信息,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,我在读ms sql的排名函数。我理解除NTILE()之外的其他函数。 假设我有以下数据: StudentID MARKS S1 75 S2 83 S3 91 S4 83 S5 93 因此,如果我在(按标记顺序描述)上做一个NTILE(2)结果会是什么,为什么? 如果它是一个实体(3)? 有人简单解释吗 它将按分

我在读ms sql的排名函数。我理解除NTILE()之外的其他函数。 假设我有以下数据:

   StudentID     MARKS  
      S1           75  
      S2           83
      S3           91
      S4           83
      S5           93  
因此,如果我在(按标记顺序描述)上做一个
NTILE(2)
结果会是什么,为什么?
如果它是一个
实体(3)

有人简单解释吗

它将按分数降序排列数据,然后将其分为两组

如果无法将数据分成相等的组,则前几个组的行数将多于后几个组

因此,NTILE(2)将为您提供

StudentID       MARKS       NTILE  
      S5           93           1 
      S3           91           1 
      S2           83           1
      S4           83           2
      S1           75           2 
StudentID       MARKS       NTILE  
      S5           93           1 
      S3           91           1 
      S2           83           2
      S4           83           2
      S1           75           3  
同样,NTILE(3)也会给你

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

将其视为bucket,NTILE(2)将生成2个bucket,其中一半行的值为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
这是输出,因为行数不均匀,所以bucket 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

事实上,我从未在生产代码中使用过NTIL,但我可以看到这样的用法:您需要将结果拆分为n个存储桶

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

从[data]中选择[field list],(NTILE(10)OVER(order by newid())-1作为段

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

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


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

在Ntile函数中,它首先计算行数并除以Ntile中传递的参数,然后根据商将行分成相等的一组,并对它们进行排序,然后剩余的行将以移位的方式由每组从顶部开始分配不会从最少的行中获取它,例如,如果组1有4行,则它将获取其组中的第5行,而不是最后一行


感谢没有使用partition子句的Ntile,只需根据Ntile(数字)中的数字分割数据集,这样:如果没有行是7,例如:1,1,1,2,3,4,5 Ntile(3)将给出3,2,2。我是怎么得到3,2,2的?。首先假设7等于6(少一个等于6),6/3等于2,2,2,然后加+!到第一个分区。如果行数为偶数,则没有问题。只需划分数据集


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

如果您在大型集合上进行ntile,您可以使用上ntile的最小值(或下一个的最大值)作为中位数的代理。这比在很多行上运行中间值要便宜。不,你不能。如果每次运行查询时都希望得到正确的答案,则不会出现这种情况。