【问题标题】:SQL weighted average of by dates with missing rows缺少行的按日期的 SQL 加权平均值
【发布时间】:2015-08-10 16:57:31
【问题描述】:

我有下表:

    Date | Flag|  Val   |  Weight
      1  |  A  |    5   |    2    
      1  |  B  |    5   |    2    
      2  |  A  |    10  |    1     
      3  |  A  |    10  |    1
      3  |  B  |    10  |    1

如果我按 Flag 列分组 SUM(val * weight) / SUM(weight),那么我将得到 A:7.5,B:6.67。但是,这是因为第二个日期没有 B 的条目。我想将其视为零值。所以我真的应该得到 A:7.5,B:5。

如何在不修改表并为 B 添加零行的情况下使用 SQL?

【问题讨论】:

  • 是 MySQL 还是 SQL Server?
  • 如果那是你想要做的,那就不叫weighted average
  • MySQL。是的,它是加权平均值,但其中一行没有被包括在内,因为该行没有数据。
  • 即使你说的已经完成了,它也会返回相同的结果,因为 0 不会改变任何东西。

标签: sql weighted-average


【解决方案1】:

您需要创建一个框架表。所以你有每个日期的标志记录。像

SELECT * FROM (SELECT DISTINCT Date From Table) t1, (SELECT DISTINCT Flag From Table) t2;

然后,您可以使用 COALESCE(0) 离开联接,并且当您分组时,您可以使用 count 来获取记录数。

【讨论】:

    【解决方案2】:

    基于Brad answer

    你可以这样做:

    CREATE TABLE tbValues (`Date` int, `Flag` char, `Val` float, `Weight` float);
    
    INSERT INTO tbValues
        SELECT 1, 'A',  5, 2 UNION
        SELECT 1, 'B',  5, 2 UNION
        SELECT 2, 'A', 10, 1 UNION
        SELECT 3, 'A', 10, 1 UNION
        SELECT 3, 'B', 10, 1 ;
    
    CREATE TABLE tbTemp
    as (SELECT * FROM (SELECT DISTINCT Date, Weight From tbValues) t1, (SELECT DISTINCT Flag From tbValues) t2);
    

    然后:

    SELECT 
        SUM( IFNULL(V.Val,0) * IFNULL(T.Weight,0) ) / SUM( T.Weight ) 
    FROM tbValues V
    RIGHT JOIN tbTemp T
        ON V.Date = T.Date
        AND V.Flag = T.Flag
    GROUP BY
        T.Flag;
    

    这里有一个活生生的例子: SqlFiddle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多