【问题标题】:Good way to format decimal in SQL Server在 SQL Server 中格式化小数的好方法
【发布时间】:2011-02-20 12:26:39
【问题描述】:

我们在数据库中存储一个小数(9,8)。它可以在小数点后有任意位数(嗯,不超过 8 位)。我很沮丧,因为我想将它显示为人类可读的文本,作为在服务器上创建的更大字符串的一部分。我希望小数点右侧的小数与非零一样多,例如:

0.05
0.12345
3.14159265

都很好

如果我这样做了

CAST(d AS varchar(50)) 

我得到如下格式:

0.05000000
0.12345000
3.14159265

如果我在转换为 varchar 之前转换/转换为浮点数或其他类型,我会得到类似的输出。我知道怎么做固定的小数位数,比如:

0.050
0.123
3.142

但这不是我想要的。

是的,我知道我可以通过复杂的字符串操作(REPLACE 等)来做到这一点,应该有一个很好的方法来做到这一点。

【问题讨论】:

  • 在这种情况下,您会发现报告工具在格式化方面比数据库做得更好。
  • 不必赘述,但在 SQL 中这样做很麻烦的原因是 SQL 不是为格式化数据而设计的;它旨在返回数据。因此,通过将小数返回给调用应用程序并让它按照您想要的方式格式化它会更容易完成。从变通方法中可以看出,SQL 在字符串操作方面很糟糕。

标签: sql sql-server tsql formatting decimal


【解决方案1】:

玩弄(sql server),我发现首先转换为浮动是诀窍..

select cast( cast(0.0501000 as float) as varchar(50) )

产量

0.0501

【讨论】:

  • 这在您编写时有效,但不适用于我表中的数据。知道原因后我会回复。
  • "3.14159265" 使用这种方法返回 "3.14159"。我还担心浮点数的近似性质,它可能无法完全表示小数
  • 正在工作,只是一个错字,仍然存在 AdaTheDev 报告的问题(对我来说不是问题,但可能是其他人的问题)
【解决方案2】:

除了相当直接的操作之外,我会考虑在您的调用代码中执行此操作,而不是 tbh,因为我认为 SQL 通常最好从数据库中按原样返回数据,然后保留格式这取决于它的名字,这很可能更适合字符串操作。尤其是当您发现自己正在努力实现目标时。

【讨论】:

  • 正如我在帖子中所说,调用代码需要一个字符串。根据数据库中的其他数据,这个数字可能是也可能不是该字符串的一部分。
【解决方案3】:

Code copied almost verbatim from here(还讨论了模式 0 中浮点格式的 6 位限制):

DECLARE @num3 TABLE (i decimal(9, 8))

INSERT  @num3
        SELECT  0.05
        UNION ALL
        SELECT  0.12345
        UNION ALL
        SELECT  3.14159265 
SELECT  i
       ,CASE WHEN PATINDEX('%[1-9]%', REVERSE(i)) < PATINDEX('%.%', REVERSE(i))
             THEN LEFT(i, LEN(i) - PATINDEX('%[1-9]%', REVERSE(i)) + 1)
             ELSE LEFT(i, LEN(i) - PATINDEX('%.%', REVERSE(i)))
        END 'Converted'
FROM    @num3

【讨论】:

  • @Brad - 不幸的是,如果 必须 在 SQL 中完成,字符串操作是一种方法 - 您可以将操作包装在 UDF 中。您可以改用 SQL CLR,但我自己并不想去那里。恕我直言,投票有点苛刻 - 特别是因为他们不会损害返回的数据。
  • @AdaTheDev - 我会避免使用标量 UDF,因为它们往往表现不佳。
  • @Brad - 我同意应该有一个更简单的语法,但它执行的操作实际上只是为了产生结果而必须做的(PATINDEX、REVERSE 和 LEN 都是确定性的所以每个只会被评估一次)。唯一可能更有效的可能是一个 CLR 函数,它直接逐位格式化小数。不过,我会对其进行基准测试,尤其是在您运行数千行时。
猜你喜欢
  • 2015-06-21
  • 1970-01-01
  • 2010-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-23
  • 2010-11-05
相关资源
最近更新 更多