【问题标题】:SQL to add a summary row to MySQL result setSQL 向 MySQL 结果集添加摘要行
【发布时间】:2015-09-16 15:19:34
【问题描述】:

如果我有一个 MySQL 表,例如:

我想使用 SQL 来计算 PositiveResult 列和 NegativeResult 列的总和。通常我可以简单地在查询中使用SUM(PositiveResult)

但是,如果我想更进一步,将总数放在结果集底部的一行中:

这可以在数据级别实现还是表示层问题?如果可以通过 SQL 完成,我该怎么做?我是一个 SQL 新手。

感谢受访者。我现在将与客户核实情况。

另外,是否可以添加一个文本列,使最后一行数据的值不显示在摘要行中?像这样:

【问题讨论】:

    标签: mysql sql resultset summary


    【解决方案1】:

    我也会在表示层执行此操作,但您可以执行 MySQL...

    DROP TABLE IF EXISTS my_table;
    
    CREATE TABLE my_table
    (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
    ,pos DECIMAL(5,2)
    ,neg DECIMAL(5,2)
    );
    
    INSERT INTO my_table VALUES
    (1,0,0),
    (2,1,-2.5),
    (3,1.6,-1),
    (4,1,-2);
    
    
    SELECT COALESCE(id,'total') my_id,SUM(pos),SUM(neg) FROM my_table GROUP BY id WITH ROLLUP;
    
    +-------+----------+----------+
    | my_id | SUM(pos) | SUM(neg) |
    +-------+----------+----------+
    |     1 |     0.00 |     0.00 |
    |     2 |     1.00 |    -2.50 |
    |     3 |     1.60 |    -1.00 |
    |     4 |     1.00 |    -2.00 |
    |  total|     3.60 |    -5.50 |
    +-------+----------+----------+
    5 rows in set (0.02 sec)
    

    这是修改后问题的 hack - 它不是很漂亮,但我认为它有效...

    SELECT COALESCE(id,'') my_id
         , SUM(pos)
         , SUM(neg)
         , COALESCE(string,'') n
      FROM my_table 
     GROUP 
        BY id
         , string
      WITH ROLLUP
    HAVING n <> '' OR my_id = ''
    ;
    

    【讨论】:

    • 我同意更好的演示级别应该处理总计。你的查询给出了完美的输出!。
    • 这几乎是完美的。但如果表格包含文本列,则最后一行数据的值将包含在汇总行中。这完全可以克服吗?我注意到COALESCE 实际上也不是必需的。
    • 如果有文本列,汇总行是否可以显示空白或空?
    • 我在原始问题的末尾发布了我的意思。
    • 谢谢。无论如何,表示层仍然是最整洁的方法。
    【解决方案2】:
    select keyword,sum(positiveResults)+sum(NegativeResults)
    from mytable
    group by
    Keyword
    

    如果需要绝对值放 sum(abs(NegativeResults)

    【讨论】:

      【解决方案3】:

      这应该在 SQL 查询层之上至少一层处理。

      初始查询可以获取详细信息,然后应用层可以计算聚合(汇总行)。或者,可以使用第二个 db 调用直接获取摘要(尽管这仅适用于摘要的计算非常耗费资源并且确实需要第二个 db 调用的情况 - 大多数时候是应用层可以更有效地做到这一点)。

      结果的排序/布局(即“页脚”摘要行之后的详细信息行)应在表示层处理。

      【讨论】:

      • 我会同意,但我会看看客户的决定。
      • 我可以同情:)。如果您的应用开发团队和/或客户坚持一个查询返回详细信息 + 总结,那么您可以使用 UNION 或 SQL 窗口函数(如果可以的话)一次完成所有操作,但是您将拥有确保您创建某种排序,以便以正确的方式返回行。在没有明确指定确切顺序的情况下,不要永远依赖数据库以特定顺序返回行!
      【解决方案4】:

      我建议在表示层执行此操作。在 SQL 中做这样的事情也是可能的。

      create table test (
        keywordid int, 
        positiveresult decimal(10,2), 
        negativeresult decimal(10,2)
      );
      insert into test values 
      (1, 0, 0), (2, 1, -2.5), (3, 1.6, -1), (4, 1, -2);
      
      select * from (
          select keywordid, positiveresult, negativeresult
          from test
            union all
          select null, sum(positiveresult), sum(negativeresult) from test
      ) main
      order by
      case when keywordid is null then 1000000 else keywordid end;
      

      如果 keywordid 为空,我使用任意高的数字添加了排序,以确保视图可以轻松地拉出排序的记录集以进行显示。

      Result:
      +-----------+----------------+----------------+
      | keywordid | positiveresult | negativeresult |
      +-----------+----------------+----------------+
      |         1 |           0.00 |           0.00 |
      |         2 |           1.00 |          -2.50 |
      |         3 |           1.60 |          -1.00 |
      |         4 |           1.00 |          -2.00 |
      |      NULL |           3.60 |          -5.50 |
      +-----------+----------------+----------------+
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-22
        相关资源
        最近更新 更多