我有一个包含希腊格式数字的 varchar 列的 SQL 表(。作为千位分隔符,逗号作为小数点分隔符)
经典的转换
CONVERT(numeric(10,2),REPLACE([value],',','.'))
Run Code Online (Sandbox Code Playgroud)
不起作用,因为 . (千位分隔符)杀死转换
例如尝试
CONVERT(numeric(10,2),REPLACE('7.000,45',',','.'))
Run Code Online (Sandbox Code Playgroud)
我想将这些值转换为数字(10,2)
有关如何处理的任何建议?
问题比较简单。我需要计算 3 列,其中中间结果是大数,并且我在早期遇到问题,SQL Server 基本上四舍五入,无论是否进行任何强制转换/转换。
例如,让我们做一个简单的除法 1234/1233。计算器将产生 1,00081103000811。但是当我在 SQL Server 上执行此操作时,我们得到以下信息:
-- Result: rounded at 1.000811000... with trailing zeroes up until the 37 precision
SELECT CAST(CAST(1234 AS DEC(38,34))/CAST(1233 AS DEC(38,34)) AS DEC(38,37))
-- Result: rounded at 1.000811
SELECT CONVERT(DECIMAL(38,32), 1234)/CONVERT(DECIMAL(38,32),1233)
-- Correct result at 1,00081103000811
-- But this requires the zeroes to be put in manually when you don't
-- even know the precision of the end result
SELECT 1234.0/1233.00000000000000
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种自动舍入?当您无法确定一个数字(int 或 dec 部分)有多大时,计算超长十进制值的最佳方法是什么,因为该表可以包含各种不同的值?
谢谢!
我有这种情况,看起来 MySQL 正在采用最大的十进制值并尝试将其他值转换为该值。
问题是这个查询是由外部库生成的,所以我无法控制这个代码,至少在这个级别。你知道如何解决这个问题吗?
SELECT 20 AS x
UNION SELECT null
UNION SELECT 2.2;
+------+
| x |
+------+
| 9.9 | -- why from 20 to 9.9
| NULL |
| 2.2 |
+------+
Run Code Online (Sandbox Code Playgroud)
预期结果
+------+
| x |
+------+
| 20 | -- or 20.0, doesn't matter really in my case
| NULL |
| 2.2 |
+------+
Run Code Online (Sandbox Code Playgroud)
添加更多上下文,我使用 Entity Framework 6 和扩展库http://entityframework-extensions.net/批量保存更改,特别是方法 context.BulkSaveChanges();,该库使用“select union”创建查询.
我正在运行 SQL Server 2012
SELECT
0.15 * 30 / 360,
0.15 / 360 * 30
Run Code Online (Sandbox Code Playgroud)
结果:
0.012500,
0.012480
Run Code Online (Sandbox Code Playgroud)
这个对我来说更令人困惑:
DECLARE @N INT = 360
DECLARE @I DECIMAL(38,26) = 0.15 * 30 / 360
DECLARE @C DECIMAL(38,26) = 1000000
SELECT @C * @I * POWER(1 + @I, @N) / ( POWER(1 + @I, @N) - 1 )
SELECT @C * (@I * POWER(1 + @I, @N) / ( POWER(1 + @I, @N) - 1 ) )
Run Code Online (Sandbox Code Playgroud)
第一个选择给了我正确的结果:12644.44022 第二个截断结果:12644.00000
我试图更好地理解 SQL 中的数字类型,并且读到十进制类型总是需要 17 个字节。但是,MS Docs列出了一个表格,指示使用的空间量取决于小数的精度。所以我尝试使用该datalength
功能对其进行测试。
create table tbl_TestDec(dec1 decimal(19,4), dec2 decimal(20,4), dec3 decimal(9,4))
insert into tbl_TestDec
select 1, 1, 1
select datalength(dec1), datalength(dec2), datalength(dec3) from tbl_TestDec
Run Code Online (Sandbox Code Playgroud)
这输出:
5 5 5
Run Code Online (Sandbox Code Playgroud)
我期待9 13 5
或17 17 17
。我正在使用 SQL Server 2005。所有小数都是 vardecimal 还是我误解了 datalength 函数?
将两个整数存储为小数有什么缺点?
我将资产详细信息存储在表中,每种资产类型都有自己的表(每种资产都非常不同)并使用另一个表来定义资产表,因此每个资产表都有一个整数 id,每个资产也有一个整数 id。
我有两种不同的场景,这可能很方便:
有一个“审计”表,其中存储如下信息:这个用户对那个项目做了这个
有人被指派处理这种类型的资产。我正在考虑将它存储为 assetType.assetID,因此资产类型 5 和 id 99 将是十进制 5.99
我很少需要根据 5.99 进行选择,我只会查询存储 5.99 的记录,然后将其拆分并使用函数转到表 5 的记录 99。
我无法将资产 ID 绑定到特定表;assetType 是表中引用资产表的条目的 id(定义表名、主键列等内容),因此似乎我无法以任何方式使用外键约束。
有很多资产表,例如asset_tmv
和asset_backflow
。资产根据它所在的表分配类型,因为要为每个资产存储的数据差异很大。
我意识到我可以使用 2 个整数字段来实现这一点。我想知道的是:缺点是什么?
我认为我对精度与比例的理解可能不正确,因为以下示例产生的值对我来说没有意义。decimal(32, 14)
轮结果到6位小数,而decimal(18, 14)
发到19我的理解小数的是decimal(p, [s])
,这里p
是数字的总数,s
是数字的小数点(IG后的数字,decimal(10, 2)
会导致8位,左侧是小数和 2 位数字)。这不正确吗?
我创建了一个小例子来说明看似奇怪的行为:
--------------------
-- Truncates at pipe
-- 1.043686|655...
--------------------
declare @dVal1 decimal(32, 14) = 10
declare @dVal2 decimal(32, 14) = 9.581419815465469
select @dVal1 Val1, @dVal2 Val2, @dVal1 / @dVal2 CalcResult
----------------
-- Most accurate
----------------
declare @dVal3 decimal(18, 14) = 10
declare @dVal4 decimal(18, 14) = 9.581419815465469
select @dVal3 Val3, @dVal4 Val4, @dVal3 / @dVal4 CalcResult
Run Code Online (Sandbox Code Playgroud)
那么问题来了,我缺少什么来理解这一点?我读过的文章和 msdn 博客似乎没有提供清晰的信息(至少对我的思考过程而言)。有人可以向我解释为什么更高的精度似乎会导致比例损失?
将数字 1 存储在定义为的字段中是否符合 SQL92 NUMERIC 3,3
?
关于什么 DECIMAL 3,3
?
这是否意味着精度是浮动小数位或静态的,即使它们都为零也必须有 3 个小数位?
我decimal(4, 4)
在 MS SQL Server 2008 R2 中有一个列。如果我理解正确,这意味着:
Precision
of 4,即小数点后最多可存储四位Scale
of 4,即一共可以存储四位数字当我运行更新命令将列设置为1
( update myTable set myDecimalColumn=1
) 时,出现此错误:
将数字转换为数字数据类型时出现算术溢出错误。
我不明白这是怎么回事。 1
小数点后没有数字,只有一位长。
由于懒惰和方便,我在我的 PostgreSQL 数据库中以不受限制的数字类型集成了来自合作伙伴的大量数据。
然而,现在看来,根据该合作伙伴的不同出货量,数字的比例从零到超过 20 个小数位(或比例)不等,这没有多大意义,可能会无缘无故地消耗大量存储空间. 所以我想将我的数字字段限制在一个合理的范围内。
然而,因为我的合作伙伴没有提供任何建议,我想确定我的数据集中每个尺度的出现,以可能在 0 和 20 之间确定一个合理的中间地带(零显然不是一个选项,并且考虑到 1700 万行-算,总金额将受到我的决定的影响)。
在接下来的四舍五入过程中也需要使用它,以避免实际增加标度为零的值的标度。
长话短说,对于存储为任意数字的特定数字,计算它的最佳方法是什么?
我能想到的最好的方法是,但有没有更优雅的方法可以在不转换为文本的情况下做到这一点?
SELECT
my_numeric,
COALESCE(
char_length( -- Finding size of string extracted by a...
substring(my_numeric::text,'\.(\d*)') -- regexp to return all digits right from '.'
), -- but if scale is 0 substring return NULL
0 -- so I handled this inside a COALESCE
) AS my_numeric_scale
FROM
(VALUES
(0.1::numeric),
(0.12),(0.123),
(0.1234),
(0.12345),
(0.123456),
(0.000001),
(0.100000)
) foo …
Run Code Online (Sandbox Code Playgroud) 如何计算所有小数位直到第一个零
例如,我有一个名为 x 的列,其中包含一个数值数据类型值 1.955000000
我想计算没有零的小数位。所以在这里我希望查询输出 3 而不是 9(带零)
我有一个不同报告周期的学生和成绩数据库。每个报告周期都有一个唯一的 ID,每个主题也有一个唯一的 ID。学生每个科目可以有不止一位老师,所以我需要平均给定的成绩,并只给出他们成绩的平均成绩。原始数据示例如下:
+--------------+------+-----+----+-------------+---+
| 223599152142 | 12 | 92 | 3 | Mathematics | 0 |
| 223599152142 | 12 | 92 | 3 | Mathematics | 3 |
| 223599152142 | 12 | 92 | 7 | History | 3 |
| 223599152142 | 12 | 92 | 12 | Economics | 3 |
| 223599152142 | 12 | 92 | 12 | Economics | 4 |
| 223599152142 | 12 | 92 | 26 | Latin | …
Run Code Online (Sandbox Code Playgroud) 我有一个简单的架构和 MWE 查询。
架构:
CREATE TABLE ttable (
tcol Numeric(19,4)
)
Run Code Online (Sandbox Code Playgroud)
询问:
INSERT INTO ttable (tcol) VALUES ('123.45678');
SELECT * FROM ttable;
Run Code Online (Sandbox Code Playgroud)
结果:
123.4568
在这种情况下,我失去了精度。我输入了五位小数,但 Postgres 自动四舍五入。我希望这是一个错误,或者至少是我可以检测到的某种警告,以便我可以告诉用户精度损失。
我怎样才能做到这一点?
编辑:
这个问题显然不是这个问题的重复。在那个问题中,用户正在使用一个客户端应用程序,该应用程序对低于存储精度的值进行四舍五入。我的问题是关于 Postgres 本身对数据进行四舍五入以适合,而不是客户端显示。对于那些比这两个问题的标题看得更远的人来说,这将是显而易见的。
decimal ×13
sql-server ×6
datatypes ×4
postgresql ×3
t-sql ×3
mysql ×2
cast ×1
mysql-5.6 ×1
query ×1
sql-standard ×1
string ×1
union ×1