春节期间是娱乐的时间,不过如果整天娱乐不学习浑身都难受,所以偶尔还是要调剂一下,娱乐之余就要学习。
每天进步一点点
(图源 :pixabay)
话说,前段时间在研究使用HiveSQL查询历史挂单以及成交,发现计算出来的价格小数点后有很多位数字,这让生成的表格看起来不是那么规整。
那么有没有什么办法,让数字看起来更规整一些呢?其实从应用的角度看,我们大可以不用关心这点,因为SQL返回的数据一般都要再次进行处理的。
比如说,在Python中,我们就可以通过round()
或者格式化输出,来实现我们想要的功能,相应代码如下:
使用round()
:
a = 1.1118
b = round(a, 3)
print(b)
使用格式化输出:
a = 1.1118
print(f'{a:.3f}')
其它语言中也都有类似的机制,就不再赘述了。
现在的问题是,如何使用SQL(SQL Server)来达成我们的目标,而不是使用第三方语言再对数据进行额外处理。
首先,尝试使用round函数,为了便于说明问题,我们直接取一个包含N多位小数的数字,而不是直接从数据库中查询中计算出来的小数。
执行如下查询:
select round(0.3694826767916468913, 3);
结果如下:
Reveal spoiler
咦,这个结果是什么鬼?把0.3694826767916468913
变成了0.3690000000000000000
,看起来更不舒服了。
看了一下微软官网上关于round函数的介绍,其中返回值部分是这样说的:
Reveal spoiler
也就是说,根据输入的数据来判断输出的类型,所以对于一个小数点后有N位小数的数字而言,它返回的数字也是包含N位小数,也就是说在[SQL Server] SQL中,round
只负责四舍五入,不负责截短,这和我想要的不一致呀?
如果我们使用的MySQL,那么应该可以用类似如下语句来负责截短:
SELECT TRUNCATE(135.376, 2);
然而无论是文档以及实测,都表明MS SQL是不支持TRUNCATE
函数的,所以得另想办法。
这时候就得请出CAST
函数了,其语法如下:
CAST ( expression AS data_type [ ( length ) ] )
也就是说,可以表达式转换成我们需要的数据类型,回到我们的例子中,我们就可以使用如下语句来处理我们的数据:
SELECT CAST (0.3694826767916468913 AS decimal (18,3));
关于decimal数据类型,表示为decimal[ (p[ ,s] )]
,其实就是我们常用的十进制数,详情可以参考这里:decimal and numeric (Transact-SQL)。
其中p
(精度),代表要存储的十进制数字的最大总数,默认为18;s
(比例),代表存储在小数点右侧的小数位数。
上述查询返回如下结果:
Reveal spoiler
这是我们想要的结果,所以之前文章中的那个SQL就可以修改为:
select top 200 current_pays, current_pays_symbol, open_owner, open_pays, open_pays_symbol,
CAST(current_pays/open_pays AS decimal (18,3))as price, timestamp
from VOFillOrders
where current_owner='oflyhigh'
order by timestamp desc
也就是说,将之前SQL中的:
amount_to_sell/min_to_receive as price
修改为:
CAST(current_pays/open_pays AS decimal (18,3))as price
对比下输出,修改之前:
Reveal spoiler
修改之后:
Reveal spoiler
很明显,后者舒服多啦,更方便我们阅读和分析。
好好学习 天天向上
学霸都是这样的,走到哪学到哪。
👍👍
仔细看了很久,除了看不懂之外就剩下看不懂了。
真厉害,像你学习!
好勤快的O哥😁
如果能向O哥这么努力,估计我厦大就考上了😂