我正在尝试执行此查询,这是我的过程的一部分,以及创建问题的那个:
select SUM(
CASE --DT007
WHEN PRO.Sens_Mnt_Brut = 'D'
THEN '-' || TO_CHAR(PRO.Mnt_Brut,'99999999999,99')
WHEN PRO.Sens_Mnt_Brut = 'C'
THEN '' || TO_CHAR(PRO.Mnt_Brut,'99999999999,99')
END) OVER(PARTITION BY PRO.Num_Est_Remise) - SUM(TO_CHAR(PRO.Mnt_Comm_Tot_Ope,'99999999999,99')) OVER(PARTITION BY PRO.Num_Est_Remise))--DT015
From dlc_pr_operation pro;
执行后我收到此错误:
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause:
*Action:
是因为从char转换为数字以及我要添加到查询中的逗号还是别的。
提前感谢您的帮助。
答案 0 :(得分:3)
你在数字和字符串之间进行了大量的显式和隐式转换,并且不一致和假设使你绊倒。但无论如何它们都是不必要的 - 你根本不需要转换为字符串。您的查询可以重写为:
select SUM(
CASE PRO.Sens_Mnt_Brut WHEN 'D' THEN -1 ELSE 1 END * PRO.Mnt_Brut
) OVER (PARTITION BY PRO.Num_Est_Remise)
- SUM(PRO.Mnt_Comm_Tot_Ope) OVER(PARTITION BY PRO.Num_Est_Remise)
From dlc_pr_operation pro;
根据Sens_Mnt_Brut
标志决定,Mnt_Brut
是应该按原样使用还是应该否定,并在适当的时候将它乘以1或-1。
您的方法至少有两个问题。您将数字转换为具有显式格式模型的字符串,然后将它们隐式转换回数字以对它们求和;这意味着(a)您依靠NLS设置进行隐式转换,并且(b)您正在形成的字符串无论如何都无法使用您的显式模型转换回来。
让我们从一些虚拟数据开始,这些数据会进入你的第一个分支:
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
)
select to_number('-' || TO_CHAR(PRO.Mnt_Brut,'99999999999,99')) from dlc_pr_operation pro;
ORA-01722: invalid number
如果你看一下它形成的字符串,你会看到:
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
)
select '-' || TO_CHAR(PRO.Mnt_Brut,'99999999999,99') from dlc_pr_operation pro;
'-'||TO_CHAR(PRO
----------------
- 12,35
由于所有空格,该字符串的转换失败。您可以使用略微修改的格式模型来避免这种情况:
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
)
select to_number('-' || TO_CHAR(PRO.Mnt_Brut,'FM99999999999,99')) from dlc_pr_operation pro;
TO_NUMBER('-'||TO_CHAR(PRO.MNT_BRUT,'FM99999999999,99'))
--------------------------------------------------------
-12,35
但仅限于您的NLS设置,尤其是NLS_NUMERIC_CHARACTERS,是正确的。如果我在执行alter session set nls_numeric_characters = '.,'
之后运行相同的查询,那么这也会得到ORA-01722,因为您使用了固定的逗号。您可以显式更改会话,也可以从使用固定,
切换到通用D
小数分隔符:
alter session set nls_numeric_characters = '.,';
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
)
select to_number('-' || TO_CHAR(PRO.Mnt_Brut,'FM99999999999,99')) from dlc_pr_operation pro;
ORA-01722: invalid number
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
)
select to_number('-' || TO_CHAR(PRO.Mnt_Brut,'FM99999999999D99')) from dlc_pr_operation pro;
TO_NUMBER('-'||TO_CHAR(PRO.MNT_BRUT,'FM99999999999D99'))
--------------------------------------------------------
-1234.56
在整个查询过程中,这仍然会隐式转换回数字。
从这个答案的开头使用修改后的查询(如果你能记得那么远)而不是一些虚拟数据给出输出:
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
union all select 'X', 123.45, 2, 4 from dual
union all select 'Y', 456.78, 3, 4 from dual
)
select SUM(
CASE PRO.Sens_Mnt_Brut WHEN 'D' THEN -1 ELSE 1 END * PRO.Mnt_Brut
) OVER (PARTITION BY PRO.Num_Est_Remise)
- SUM(PRO.Mnt_Comm_Tot_Ope) OVER(PARTITION BY PRO.Num_Est_Remise) as result
From dlc_pr_operation pro;
RESULT
----------
-1235,56
575,23
575,23
由于没有转换,您的NLS设置现在不重要;除了最终结果由客户端自动使用会话的小数分隔符格式化,因此在此示例中它仍然显示逗号分隔符,数字字符设置为',.'
。如果我将会话更改为'.,'
,我会看到:
RESULT
----------
-1235.56
575.23
575.23
您实际想要的结果是否不太明确。包含其他列可能很有用,但您还需要检查您是否真的需要分析函数,而不仅仅是聚合。
你在评论中说:
除非你将金融金额存储为整数 - 基本上是便士/美分而不是英镑/欧元/美元 - 但是希望以更友好的方式展示它们,这并不是真的有意义。在这种情况下,你应该将它们除以100,而不是将它们分成字符串:它是一个数字(16.0),但我想在最后两个数字之前加一个逗号
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 123456, 100, 2 from dual
union all select 'X', 12345, 200, 4 from dual
union all select 'Y', 45678, 300, 4 from dual
)
select (SUM(
CASE PRO.Sens_Mnt_Brut WHEN 'D' THEN -1 ELSE 1 END * PRO.Mnt_Brut
) OVER (PARTITION BY PRO.Num_Est_Remise) / 100)
- (SUM(PRO.Mnt_Comm_Tot_Ope) OVER(PARTITION BY PRO.Num_Est_Remise) / 100) as result
From dlc_pr_operation pro;
RESULT
----------
-1235.56
575.23
575.23
...假设(再次)两个被求和的值都是这样存储的;如果您愿意,也可以减去两个总和并将总数除以100。