varchar型分数转换成小数

hongchan5229 2018-07-23 02:49:45
表里面有字段为varchar型的分数,现需要将其取出计算,请教怎么处理!

注:我试过使用cast,依然是不能解决这个问题的。

语句:select ftbl,qua from TB

查询返回的值

ftbl | qua
-----
1/2 | 5
1/3 | 20
1/5 | 30
1/2 | 10
1/6 | 10

select ftbl , qua, ftbl * qua as HJ from TB



select ftbl , qua, cast(ftbl as numeric(10,2)) * qua as HJ from TB

都会出错提示,都是提示这个






...全文
638 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
zjcxc 元老 2018-07-24
  • 打赏
  • 举报
回复
多加一列,存储的时候先把数据算好存进去,用的时候直接用这个存储的结果
中国风 2018-07-24
  • 打赏
  • 举报
回复
这类要效率高可用DDL函数去实现
可参照OA系列存儲過程
https://blog.csdn.net/roy_88/article/details/6292123
二月十六 版主 2018-07-24
  • 打赏
  • 举报
回复
ftbl 是个字符串,不是一个数值,所以不能直接做数值操作,如果ftbl 的数据全是这样a/b的情况,用#5版主的方法就行,如果可能还有a/b*c-d 这样的类型,就得考虑动态执行或者是存储数据的时候就存储计算完之后的数据
吉普赛的歌 版主 2018-07-24
  • 打赏
  • 举报
回复
原来的确实有问题, 改了下:
DECLARE @t TABLE (
ftbl VARCHAR(50),
qua INT
)
INSERT INTO @t
SELECT '1/2',5
UNION ALL SELECT '1/3',20
UNION ALL SELECT '1/5',30
UNION ALL SELECT '1/2',10
UNION ALL SELECT '12/600',10

SELECT
*,
SUBSTRING(ftbl,1,CHARINDEX('/',ftbl)-1) AS [分子]
,
SUBSTRING(ftbl,CHARINDEX('/',ftbl)+1,LEN(ftbl)) AS [分母]
,
CAST(SUBSTRING(ftbl,1,CHARINDEX('/',ftbl)-1) AS NUMERIC(18,5))
/
CAST(SUBSTRING(ftbl,CHARINDEX('/',ftbl)+1,LEN(ftbl)) AS NUMERIC(18,5)) AS [化为小数]
FROM @t



zjcxc 元老 2018-07-24
  • 打赏
  • 举报
回复
任意位数的分母截取人家不是给你写好了么?
CAST(RIGHT(ftbl,CHARINDEX(ftbl,'/')+1) AS NUMERIC(18,5))
hongchan5229 2018-07-24
  • 打赏
  • 举报
回复
引用 5 楼 yenange 的回复:
USE tempdb
GO
IF OBJECT_ID('t') IS NOT NULL DROP TABLE t
GO
CREATE TABLE t (
ftbl VARCHAR(50),
qua INT
)
INSERT INTO t(ftbl,qua)
SELECT '1/2',5
UNION ALL SELECT '1/3',20
UNION ALL SELECT '1/5',30
UNION ALL SELECT '1/2',10
UNION ALL SELECT '1/6',10

--1. 增加一个计算列
ALTER TABLE t ADD ftbl_numeric AS
CAST(LEFT(ftbl,CHARINDEX(ftbl,'/')+1) AS NUMERIC(18,5))
/
CAST(RIGHT(ftbl,CHARINDEX(ftbl,'/')+1) AS NUMERIC(18,5))
PERSISTED

--2. 查看
SELECT * FROM t




加个计算列就好了, 效率很高, 而且你想用来组合计算也很方便。


我只是个DBUSER,没有那么多权限

但根据你参考了你思路去写了另一种的

1 / cast(substring(ftbl,3,2)as numeric(8,2))

我这里的数据分子肯定是1的,所以就不用考虑了,就这个分母取数问题。

不过我认为自己这方式不够灵活,如果达到3位数就又需要改语句了,只能应付目前
吉普赛的歌 版主 2018-07-23
  • 打赏
  • 举报
回复
USE tempdb
GO
IF OBJECT_ID('t') IS NOT NULL DROP TABLE t
GO
CREATE TABLE t (
ftbl VARCHAR(50),
qua INT
)
INSERT INTO t(ftbl,qua)
SELECT '1/2',5
UNION ALL SELECT '1/3',20
UNION ALL SELECT '1/5',30
UNION ALL SELECT '1/2',10
UNION ALL SELECT '1/6',10

--1. 增加一个计算列
ALTER TABLE t ADD ftbl_numeric AS
CAST(LEFT(ftbl,CHARINDEX(ftbl,'/')+1) AS NUMERIC(18,5))
/
CAST(RIGHT(ftbl,CHARINDEX(ftbl,'/')+1) AS NUMERIC(18,5))
PERSISTED

--2. 查看
SELECT * FROM t




加个计算列就好了, 效率很高, 而且你想用来组合计算也很方便。
hongchan5229 2018-07-23
  • 打赏
  • 举报
回复
引用 1 楼 RINK_1 的回复:
先根据/拆成2部分,再转换成数值型,最后再相除。

你好,有具体语句吗?
hongchan5229 2018-07-23
  • 打赏
  • 举报
回复
引用 2 楼 yenange 的回复:
DECLARE @t TABLE (
ftbl VARCHAR(50),
qua INT
)
INSERT INTO @t
SELECT '1/2',5
UNION ALL SELECT '1/3',20
UNION ALL SELECT '1/5',30
UNION ALL SELECT '1/2',10
UNION ALL SELECT '1/6',10

SELECT
CAST(LEFT(ftbl,CHARINDEX(ftbl,'/')+1) AS NUMERIC(18,5))
/
CAST(RIGHT(ftbl,CHARINDEX(ftbl,'/')+1) AS NUMERIC(18,5))
FROM @t
/*
0.50000000000000000000
0.33333333333333333333
0.20000000000000000000
0.50000000000000000000
0.16666666666666666666
*/

版主,这只是打比方,还有过万条信息,不可能全部into吧?!
吉普赛的歌 版主 2018-07-23
  • 打赏
  • 举报
回复
DECLARE @t TABLE (
ftbl VARCHAR(50),
qua INT
)
INSERT INTO @t
SELECT '1/2',5
UNION ALL SELECT '1/3',20
UNION ALL SELECT '1/5',30
UNION ALL SELECT '1/2',10
UNION ALL SELECT '1/6',10

SELECT
CAST(LEFT(ftbl,CHARINDEX(ftbl,'/')+1) AS NUMERIC(18,5))
/
CAST(RIGHT(ftbl,CHARINDEX(ftbl,'/')+1) AS NUMERIC(18,5))
FROM @t
/*
0.50000000000000000000
0.33333333333333333333
0.20000000000000000000
0.50000000000000000000
0.16666666666666666666
*/
RINK_1 2018-07-23
  • 打赏
  • 举报
回复
先根据/拆成2部分,再转换成数值型,最后再相除。

34,594

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧