组合多个 CAST?

Combine Multiple CAST?

提问人:Dizzy49 提问时间:10/5/2023 最后编辑:Dale KDizzy49 更新时间:10/5/2023 访问量:46

问:

我有一个文件,其中包含所有内容为 nvarchar,包括所有数字,并且没有小数,因此“12.35”将仅存储为“1235”。然后我需要它输出小数点后 4 位。

我不能只是除法和转换为十进制。这很丑陋,但这有效。

SELECT CAST(CAST(rso.[NET_PRICE]    AS Decimal(20,4)) / 10)    AS Decimal(20,4) AS [Net Price]
SELECT CAST(CAST(rso.[Unit_Price]   AS Decimal(20,4)) / 10000) AS Decimal(20,4) AS [Unit Price]

有没有办法组合 CAST 或其他东西来提高效率?我有大约 2000 万条记录,每条记录大约有 40 条,所以它们正在吞噬周期。

sql-server 强制转换 进制

评论

0赞 Aaron Bertrand 10/5/2023
这并不直观,但你可以说.CONVERT(decimal(20,4), 1.0*NET_PRICE)/10
0赞 Aaron Bertrand 10/5/2023
(不过,我不知道您是否应该期望两次强制转换与一次强制转换才能真正改变对 2000 万行执行此操作的查询的性能配置文件,尤其是在您一次执行一列操作时。

答:

0赞 Knut Boehnert 10/5/2023 #1

简短的回答:不,没有更好的选择。

长答案:这取决于结果是什么,以及隐性与显性。

这一切都取决于哪些源数据可以隐式转换为“正确”值,即使间歇性隐式转换选择了最“合适”的类型。这可能不适用于某些离群值。

显示的简单测试数据和输出:

DECLARE
  @Rows
  TABLE
(
  SomeColumn    nvarchar(12)
)
;
INSERT INTO
  @Rows
VALUES
  ( N'123456' )
, ( N'4201' )
, ( N'123456789012' ) -- 1234567890123 yields truncation error
, ( N'-12345678901' ) -- -123456789012 yields truncation error
, ( N'NaN' )
;

SELECT
  SomeColumn AS OriginalString
, TRY_CAST( SomeColumn AS decimal(20,4) ) AS DecimalValue
, TRY_CAST( SomeColumn AS decimal(20,4) ) / 100 AS CalculatedSimpleValue
, CONVERT( decimal(20,4), TRY_CONVERT( decimal(20,5), SomeColumn ) / 100 ) AS CalculatedDoubleValue
FROM
  @Rows
;

结果是:

OriginalString  DecimalValue        CalculatedSimpleValue   CalculatedDoubleValue
123456          123456.0000         1234.56000000           1234.5600
4201            4201.0000           42.01000000             42.0100
123456789012    123456789012.0000   1234567890.12000000     1234567890.1200
-12345678901    -12345678901.0000   -123456789.01000000     -123456789.0100

第三列显示了强制转换后的计算将类型转换为十进制 20 以外的其他内容的位置,其中包含 4 位小数。

但是,由于这种转换代码生成结构(在 Excel 中)非常快,我喜欢 Excel 用于这些任务的函数复制列向下。

最后的技术说明:在处理字符列作为输入时,请使用 TRY_CONVERT 或 TRY_CAST,以免在 2000 万行转换工作中失败。

评论

0赞 Dizzy49 10/17/2023
我实际上使用 Excel 将多个文件合并到一个文件中进行导入。我可以在那里添加一些转换。我实际上选择不使用TRY_CAST,因为我需要知道是否存在错误,以便我弄清楚并解决它。