【问题标题】:Dynamic horizontal aggregate (AVG)动态水平聚合 (AVG)
【发布时间】:2019-08-14 09:52:18
【问题描述】:

我有一个包含 3 个浮点(可为空)列的表:

Value1  ||  Value2  ||  Value3 
NULL        NULL        100.00
10.00       20.00       NULL
10.00       10.00       100.00

我需要从这些字段中获取平均值 (value1+value2+value3 / 3),但除法器实际上是这些字段中有多少具有值。所以预期的结果是:

Value1  ||  Value2  ||  Value3 || AVG
NULL        NULL        100.00    100.00 (from 100/1)
10.00       20.00       NULL      15.00  (from 30/2)
10.00       10.00       100.00    40.00  (from 120/3)

有人可以帮忙吗?

我根据这个帖子尝试了一个解决方案: Average of multiple columns

但似乎没有用。

我也尝试在 C# 中处理这个问题,在其中我使用for 循环和一个计数器来确定分隔符,然后将它们分开。它确实有效,但我更喜欢通过查询来处理这个问题,因为当记录超过 3000 行时花费了太多时间。

我当前的查询:

SELECT *,
       (SELECT AVG(c)
        FROM   (VALUES(Value1),
                      (Value2),
                      (Value3)) T (c)) AS [Average]
FROM   tbl_trans_score

提前致谢。

【问题讨论】:

  • 您可以发布您的查询吗?
  • @mkRabbani 抱歉,我编辑了我的帖子
  • 看看我的回答.....

标签: sql sql-server select average


【解决方案1】:

你可以试试下面的脚本-

SELECT
CASE 
    WHEN (COALESCE(Value1,0)+COALESCE(Value2,0)+COALESCE(Value3,0)) = 0 THEN 0 
    ELSE
    (
        COALESCE(Value1,0)+
        COALESCE(Value2,0)+
        COALESCE(Value3,0)
    )/
    (
        CASE WHEN Value1 IS NULL THEN 0 ELSE 1 END+ 
        CASE WHEN Value2 IS NULL THEN 0 ELSE 1 END+ 
        CASE WHEN Value3 IS NULL THEN 0 ELSE 1 END 
    )
END
FROM your_table

【讨论】:

  • 我们可以在CASE WHEN中添加一个运算符吗?很抱歉我以前不知道这个,一定要试试这个。
  • 抱歉回复晚了。这对我最有效,谢谢。
【解决方案2】:

一种使用子查询和VALUES 运算符来规范化数据的方法:

SELECT V.Value1,
       V.Value2,
       V.Value3,
       A.Average
FROM (VALUES(NULL ,NULL ,100.00),
            (10.00,20.00,NULL),
            (10.00,10.00,100.00))V(Value1,Value2,Value3)
     CROSS APPLY (SELECT AVG(L.[Value]) AS Average
                  FROM (VALUES(V.Value1),
                              (V.Value2),
                              (V.Value3)) L([Value])) A;

【讨论】:

  • 这是 SQL Server 中最好的方法。
【解决方案3】:

有两种方法可以解决您的问题...

第一种方式:

SELECT AVG (Vals) AVG_COL
FROM 
(
SELECT Row_Num = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)
) ,
Value1,Value2,Value3
FROM tblFloat ) UNPIVOT_SOURCE
UNPIVOT
( 
Vals FOR Cols IN ( Value1,Value2,Value3 )
) UNPIVOT_HANDLER
GROUP BY
Row_Num

第二种方式:

SELECT
    ISNULL(
        CONVERT(
            DECIMAL(10, 2),
            1.0 *
            (
                ISNULL(Value1, 0 ) + ISNULL( Value2, 0 ) + ISNULL( Value3, 0 ) 
            )
            /
            NULLIF(
                ISNULL(SIGN(ABS(Value1)),0) + ISNULL(SIGN(ABS(Value2)),0) + ISNULL(SIGN(ABS(Value3)),0)
            ,0 )
        ) ,
        COALESCE(Value1,Value2,Value3)
    )
FROM tblFloat

【讨论】:

    猜你喜欢
    • 2020-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多