【SQL】分配函数一枚[AllotToTable]
适用环境:MSSQL 2005+。其中05需修改部分语句的写法才行,如:
--变量的声明和赋值需分开写
DECLARE @scale INT = 0 --需改为如下
DECLARE @scale INT; SET @scale = 0 --05不支持+=这样的复合运算符
SET @scale += 1 --需改为如下
SET @scale = @scale + 1
功能:
将一个数字(整数或有限小数)分配成指定份,每份一行,返回一个单列表格。
使用示例:

可见,这不是除法,而是为了尽可能公平的把数字分配完,该分配法有如下
特点:
- 不存在除不尽的情况
- 能保证所有份数之和与原数相等
- 结果精度与原数(被分配数)精度一致。3.470的精度视为0.01,所以它分成3份是1.16、1.16、1.15,而不是1.157、1.157、1.156
- 结果最多只会出现两种数值,大值与小值之差为原数精度的1个单位。即在原数精度范围内,各份之间的差值保证最小,以此做到尽可能公平的分配。如上例1.16与1.15相差0.01
- 若被分配数为NULL、或份数为NULL或0,返回0行
像这种分配法我估计在多种场景都有在用,它应该有个名堂的,只是我不知道,还请知道的猿友告知,谢谢。
函数源码:
/*--------------------
函数:分配0.01
Author:AhDung
Update:201504211157
--------------------*/
ALTER FUNCTION dbo.AllotToTable(@num DECIMAL(16,4), @div TINYINT)
RETURNS @t TABLE(Val DECIMAL(16,4))
BEGIN
IF @num IS NULL OR @div IS NULL OR @div=0 RETURN IF @div=1 --除数为1,直接返回1行
BEGIN
INSERT @t SELECT @num
RETURN
END IF @num=0 --被除数为0,直接返回@div行0
BEGIN
INSERT @t SELECT 0 FROM FMakeRows(@div)
RETURN
END /*得到@num的真实精度*/
DECLARE @scale INT=0, @numToInt DECIMAL(16,4)=@num
WHILE @numToInt % 1 <> 0
BEGIN
SET @numToInt *= 10
SET @scale += 1
END /*填充元素(舍弃过的)*/
DECLARE @roundDownItem DECIMAL(16,4)=ROUND(@num / @div, @scale, 1)
INSERT @t SELECT @roundDownItem FROM FMakeRows(@div) /*将余数均分到top n行。余数之所以不采用@num % @roundDownItem,是因为后者为1时就不对*/
DECLARE @mod DECIMAL(16,4) = @num - @roundDownItem*@@ROWCOUNT
IF @mod<>0
BEGIN
DECLARE @pow INT = POWER(10, @scale)
UPDATE TOP (CAST(ABS(@mod) * @pow AS INT)) @t
SET Val += SIGN(@mod)/@pow
END RETURN
END
函数中用到了一个叫做FMakeRows的自定义表值函数,有劳移步至这篇博文取用:http://www.cnblogs.com/ahdung/p/4195509.html,当然你可以小加改造,让它不依赖外部函数。
有尝试过用排名函数NTILE实现,借助它的组分配能力,但性能不理想,因为被分配数有多大,就得构造多大行数的表格,空间和时间都不值得。另请老鸟指点改善,谢谢。
-文毕-
【SQL】分配函数一枚[AllotToTable]的更多相关文章
- SQL SERVER 函数大全[转]
SQL Server 函数大全 一旦成功地从表中检索出数据,就需要进一步操纵这些数据,以获得有用或有意义的结果.这些要求包括:执行计算与数学运算.转换数据.解析数值.组合值和聚合一个范围内的值等. 下 ...
- SQL Server数据库--》top关键字,order by排序,distinct去除重复记录,sql聚合函数,模糊查询,通配符,空值处理。。。。
top关键字:写在select后面 字段的前面 比如你要显示查询的前5条记录,如下所示: select top 5 * from Student 一般情况下,top是和order by连用的 orde ...
- sql server 函数的自定义
创建用户定义函数.这是一个已保存 Transact-SQL 或公共语言运行时 (CLR) 例程,该例程可返回一个值.用户定义函数不能用于执行修改数据库状态的操作.与系统函数一样,用户定义函数可从查询中 ...
- SQL常用函数总结
SQL常用函数总结 这是我在项目开发中使用db2数据库写存储过程的时候经常用到的sql函数.希望对大家有所帮助: sql cast函数 (1).CAST()函数的参数是一个表达式,它包括用AS关键字分 ...
- 【转载】SQL SERVER 函数大全
SQL Server 函数大全 一旦成功地从表中检索出数据,就需要进一步操纵这些数据,以获得有用或有意义的结果.这些要求包括:执行计算与数学运算.转换数据.解析数值.组合值和聚合一个范围内的值等. 下 ...
- C标准库-数值字符串转换与内存分配函数
原文链接:http://www.orlion.ga/977/ 一.数值字符串转换函数 #include <stdlib.h> int atoi(const char *nptr); dou ...
- sql 判断 函数 存储过程是否存在的方法
下面为您介绍sql下用了判断各种资源是否存在的代码,需要的朋友可以参考下,希望对您学习sql的函数及数据库能够有所帮助.库是否存在if exists(select * from master..sys ...
- DB2 SQL 日期函数
DB2 SQL 日期函数1:CURRENT TIMESTAMP 函数:获取当前日期时间语法:CURRENT TIMESTAMP参数:当前日期时间返回值:当前日期时间 2:CURRENT DATE 函数 ...
- Netsuite Formula > Oracle函数列表速查(PL/SQL单行函数和组函数详解).txt
PL/SQL单行函数和组函数详解 函数是一种有零个或多个参数并且有一个返回值的程序.在SQL中Oracle内建了一系列函数,这些函数都可被称为SQL或PL/SQL语句,函数主要分为两大类: 单行函数 ...
随机推荐
- js 倒计时实现
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 创业6&7
周末两天泡咖啡店. 起不来,只好下午去. 周六5点到9点. 周日3点到12点. 1)整理直播课程讲义.完成50%. 2)修改GMTC演讲稿.完成. 招行的单子还是拒了,目前还没准备好高可用的App服务 ...
- MR原理
三.MapReduce运行原理 1.Map过程简述: 1)读取数据文件内容,对每一行内容解析成<k1,v1>键值对,每个键值对调用一次map函数 2)编写映射函数处理逻辑,将输入的< ...
- Lua 协程coroutine
协程和一般多线程的区别是,一般多线程由系统决定该哪个线程执行,是抢占式的,而协程是由每个线程自己决定自己什么时候不执行,并把执行权主动交给下一个线程. 协程是用户空间线程,操作系统其存在一无所知,所以 ...
- 设置easyui input默认值
/*设置input 焦点*/ $(function () { //集体调用 $(".formTextBoxes input").each(function () { $(this) ...
- Ztree行政地区树状展示
Ztree行政地区树状展示(点击加载) 效果如下: 开始贴代码: 实体类 Item,用于对Ztree的节点展示 public class Item { private String id; priva ...
- 分享一个 C# Winfrom 下的 OutlookBar 控件的使用
最近在上网的时候,发现了这个C# 下的 OutlookBar 控件,看了一下感觉还真不错,特此记录一下. using System; using System.Drawing; using Syste ...
- Android开发之时间日期2
昨天给大家分享了一个时间和日期设置的小例子,今天发现Android的布局组件中有关于时间和日期的设置的组件,废话不多说,先给大家分享一下我的经验. 时间日期设置组件:TimePicker.DatePi ...
- 编译原理LL1文法分析表算法实现
import hjzgg.first.First; import hjzgg.follow.Follow; import hjzgg.tablenode.TableNode; import hjzgg ...
- poj 2385Apple Catching(简单dp)
/* 题意: 有两棵苹果树,每一棵苹果树每一秒间隔的掉落下来一个苹果,一个人在树下接住苹果,不让苹果掉落! 人在两棵树之间的移动是很快的!但是这个人移动的次数是有限制的,问最多可以接住多少个苹果! 思 ...