如何通过函数一起使用Sum,Cast和Partition?

问题描述 投票:1回答:5

如何通过函数一起使用Sum,Cast和Partition?

我收到错误。

将nvarchar值'693.41'转换为数据类型int时转换失败。“

我试过这个

SUM(CAST([total price] AS INT)) OVER (PARTITION BY (ProjectType)) as TotalPriceV2

完整查询如下。

SELECT 
    ID,
    [Project Manager], 
    Job#, 
    [Date], 
    [Job Type],
    first_value([Job Name]) OVER (PARTITION BY value_partition ORDER BY ID) CustomerGroup, Value_Partition 
    Customer,
    [Sales Rep1],
    DeliveryType,
    ProjectType,
    [Item Price],
    [Service Price],
    [Total Price],
    SUM(CAST([total price] AS INT)) OVER (PARTITION BY (ProjectType)) as TotalPriceV2
FROM (
    SELECT 
    ID,
    [Project Manager], Job#, [Date], [Job Type], [Job Name],Customer,[Sales Rep1],DeliveryType,ProjectType,[Item Price],[Service Price],[Total Price],
    SUM(CASE WHEN [JOB NAME] IS NULL THEN 0 ELSE 1 END) OVER (ORDER BY ID) AS Value_Partition   
    FROM Testing2
    WHERE 
    [Date] IS NOT NULL AND 
    ([Date]  NOT LIKE '0' OR JOB# NOT LIKE '0' OR [JOB TYPE] NOT LIKE '0')
    AND [Project Manager] NOT LIKE 'ITEM / SERVICE'
) AS X
sql sql-server ssms
5个回答
0
投票

首先,确定有问题的行。你正在转换为int,所以:

select price
from Testing2
where try_convert(int, price) is null and price is not null;

至少有些值会有小数点(如您的示例所示)。要查看这是否是唯一的问题,我建议下一步转换为小数:

select price
from Testing2
where try_convert(decimal(20, 4), price) is null and price is not null;

如果没有返回任何内容,则设置为。如果没有,您将需要弄清楚如何解决这些异常。

然后,我会使用小数而不是浮点来计算计算:

SUM(TRY_CAST([total price] AS DECIMAL(20, 4))) OVER (PARTITION BY (ProjectType)) as TotalPriceV2

货币金额通常应使用定点值而非近似浮点值来表示。浮点值的问题是信息可能会丢失。用reals考虑这个例子:

select cast(1000000 as real) + cast(0.01 as real),
       cast(1000000 as decimal(20, 4)) + cast(0.01 as decimal(20, 4))

0
投票

整数不会有十进制值,它会引发错误。

如果我使用它,类似于你的例子。

Declare @val nvarchar(10) = '10.24' 

select   cast (@val as int) 

我得到以下错误。

Msg 245, Level 16, State 1, Line 3
Conversion failed when converting the nvarchar value '10.24' to data type int.

现在为了避免这个错误,我可以将数字舍入到0位小数并转换为Int。此外,如果您使用sql server 2012或更高版本,我建议使用Try_Cast来避免任何实际nvarchar值的情况(它会将其转换为null)。

 Declare @val nvarchar(10) = '10.24' 

select   Try_cast (round(@val,0) as int)   as valuen

输出,我认为这将在你的sum函数中起作用。

valuen
10

0
投票

为什么不在内部查询中使用十进制(16,9)而不是int来强制转换它

SELECT 
    ID,
    [Project Manager], 
    Job#, 
    [Date], 
    [Job Type],
    first_value([Job Name]) OVER (PARTITION BY value_partition ORDER BY ID) CustomerGroup, Value_Partition 
    Customer,
    [Sales Rep1],
    DeliveryType,
    ProjectType,
    [Item Price],
    [Service Price],
    [Total Price],
    SUM([total price]) OVER (PARTITION BY (ProjectType)) as TotalPriceV2
FROM (
    SELECT 
    ID,
    [Project Manager], Job#, [Date], [Job Type], [Job Name],Customer,[Sales Rep1],DeliveryType,ProjectType,[Item Price],[Service Price],cast([Total Price] as decimal(16,9)) as [Total Price],
    SUM(CASE WHEN [JOB NAME] IS NULL THEN 0 ELSE 1 END) OVER (ORDER BY ID) AS Value_Partition   
    FROM Testing2
    WHERE 
    [Date] IS NOT NULL AND 
    ([Date]  NOT LIKE '0' OR JOB# NOT LIKE '0' OR [JOB TYPE] NOT LIKE '0')
    AND [Project Manager] NOT LIKE 'ITEM / SERVICE'
) AS X

0
投票

如果您将字符串和数字组合作为列值,并且想要总结数字。对于SQL Server 2012+,您可以使用TRY_CASTTRY_CONVERT来避免任何投射错误。

TRY_CAST (Transact-SQL)

在你的场景中,你没有使用正确的数据类型进行投射,你有像693.41这样的值,它们不能被转换为INT,而是你应该使用DECIMAL数据类型。

还有一个建议,而不是使用NOT LIKE,更好地在SQL Server中使用<>,如下所示。

更改

 ([Date]  NOT LIKE '0' OR JOB# NOT LIKE '0' OR [JOB TYPE] NOT LIKE '0')

 ([Date] <> '0' OR JOB# <> '0' OR [JOB TYPE] <> '0')

0
投票

一种可能的解决方案是首先将nvarchar值转换为decimal,然后转换为integer:

CAST(CAST([total price] AS FLOAT) AS INT)

但是,通过这种方式,如果对您很重要,则小数部分会丢失。

© www.soinside.com 2019 - 2024. All rights reserved.