MSSQL 2012 - 为啥 AVG 和 TRY_CONVERT 没有返回正确的值?

Posted

技术标签:

【中文标题】MSSQL 2012 - 为啥 AVG 和 TRY_CONVERT 没有返回正确的值?【英文标题】:MSSQL 2012 - Why is AVG & TRY_CONVERT not returning the correct value?MSSQL 2012 - 为什么 AVG 和 TRY_CONVERT 没有返回正确的值? 【发布时间】:2017-12-13 07:50:32 【问题描述】:

我正在使用 MSSQL 2012,我正在尝试在具有以下数据类型的表列上使用 AVGTRY_CONVERTnvarchar(255), NOT NULL

首先在我尝试使用 AVG 和 TRY_CONVERT 进行查询之前,这是我想通过使用此查询获取 AVG 值的数据:

这是使用 AVG 和 TRY_CONVERT 后的结果,返回 0 行。

我也尝试使用子查询,然后我返回了 18 行,但值为 NULL,我跳过了 AVG 只是为了看看我是否得到了正确的值。但似乎没有,我还包括 p.serialnumber 列表明它返回了正确的行,它只是在 TRY_CONVERT 之后出现的值 NULL。

更新!

当我执行下面哪个目标数据有一个“。”的查询时分隔符 (qtv2.qtv_qteid = 58 (而不是 63)) ,它有效!所以问题是“,”分隔符。有谁知道解决这个问题??

declare @ProjectSelection nvarchar(10)
set @ProjectSelection = 'C82007588'


SELECT AVG(TRY_CONVERT(numeric(10,5), avgcap))
FROM 
(
select qtv2.qtv_result as avgcap
from ProductionOrder PO
left join CustomerOrder co on co.CustomerOrderId=po.customerorderid
left join ProductionOrderProperty pop on pop.ProductionOrderId=po.productionorderid
left join product p on p.ProductionOrderId=po.productionorderid
left join QualityTestValues qtv on qtv.qtv_productid=p.ProductId
left join QualityTestValues qtv2 on qtv2.qtv_productId=p.ProductId

where pop.Value=@ProjectSelection and pop.name = 'project' and po.ProductTypeId = 1
and qtv2.qtv_qteid = 58 and qtv2.qtv_valid = 1 and qtv.qtv_ProductSegmentId = 144 and qtv.qtv_valid = 1
and qtv.qtv_qteid = 51 and qtv.qtv_result = 'J'

group by co.CustomerName, pop.Value, qtv2.qtv_result, p.SerialNumber
) A

结果:

(No column name)
22.200000

【问题讨论】:

以***.com/help/mcve开头。 这里的大多数人想要格式化的文本,而不是图像。 (您不能将图像复制并粘贴到您的 dbms 编辑器中...) 我无法阅读您的图片。删除它们,并将最小查询添加为 text 小数点分隔符可能有问题 - 逗号与点? @Arvo 你在这里可能是正确的,我尝试使用具有如下值的查询和目标数据:22.200000 并且有效,所以问题是这些值中的逗号分隔符我试图使用 TRY_CONVERT。有什么解决办法吗? 【参考方案1】:

您的兼容性级别如何?可以在这里找到类似的问题:

TRY_CONVERT fails on SQL Server 2012

虽然您的服务器版本是 2012,但较低的兼容性级别可能会导致 try_convert 无法在您的数据库中使用。您可以通过在您的特定数据库中运行以下代码来检查这一点,然后在例如主数据库中运行。

DECLARE @b VARCHAR(10) = '12312'
SELECT TRY_CONVERT(INT,@b)

【讨论】:

【参考方案2】:

您可以进行第一个查询并执行以下操作:

SELECT AVG(TRY_CONVERT(numeric(10,5), avgcap))
FROM 
(
    -- Insert your first query here.
) A

这应该给你数字的平均值。

编辑

这是一个应该返回 24.000000 的可行示例。

SELECT AVG(TRY_CONVERT(numeric(10,5), A))
FROM 
(
    SELECT '22.5' AS A
    UNION
    SELECT '23.5' AS A
    UNION
    SELECT '26.0' AS A
) B

【讨论】:

嗨 Danieboy,我已经对此进行了测试,它返回 1 个值及其 NULL。 使用您作为内部发布的第一个查询?返回所有值的那个。 @Mikael 尝试运行我提供的示例。【参考方案3】:

我找到了解决方案,使用 TRY_PARSE 而不是 TRY_CONVERT。

DECLARE @ProjectSelection nvarchar(10)
SET @ProjectSelection = 'C82007588'


SELECT AVG(avgcap) as avgcap
FROM 
(
    SELECT qtv2.qtv_result, TRY_PARSE( qtv2.qtv_result AS NUMERIC(10,3)) avgcap
    FROM ProductionOrder PO
        LEFT JOIN CustomerOrder co on co.CustomerOrderId=po.customerorderid
        LEFT JOIN ProductionOrderProperty pop on pop.ProductionOrderId=po.productionorderid
        LEFT JOIN product p on p.ProductionOrderId=po.productionorderid
        LEFT JOIN QualityTestValues qtv on qtv.qtv_productid=p.ProductId
        LEFT JOIN QualityTestValues qtv2 on qtv2.qtv_productId=p.ProductId
    WHERE pop.Value=@ProjectSelection 
        AND pop.name = 'project' 
        AND po.ProductTypeId = 1
        AND qtv2.qtv_qteid = 63 
        AND qtv2.qtv_valid = 1 
        AND qtv.qtv_ProductSegmentId = 144 
        AND qtv.qtv_valid = 1
        AND qtv.qtv_qteid = 51 
        AND qtv.qtv_result = 'J'
    GROUP BY co.CustomerName, pop.Value, qtv2.qtv_result, p.SerialNumber
) A`

结果: 平均上限 21264.850000

【讨论】:

以上是关于MSSQL 2012 - 为啥 AVG 和 TRY_CONVERT 没有返回正确的值?的主要内容,如果未能解决你的问题,请参考以下文章

PHP调用MsSQL Server 2012存储过程获取多结果集(包含output参数)

为啥 NSOperation 示例代码使用@try & @catch

为啥添加 try 块会使程序更快?

为啥 Try/Catch 块会创建新的变量范围?

MSSQL之try Catch的用法通俗讲解

当它应该表现得像 try/catch/finally 时,为啥使用会抛出异常?