2014-01-08 59 views
1

我有一个临时表,这是先前沉重的组合数据的结果,我必须从中创建html文档来显示。PostgreSQL,混合SUM水平和垂直

此表在短说明了情况:

DROP TABLE IF EXISTS temp11; 
CREATE TABLE temp11 (t_idx int PRIMARY KEY, mydate text, myclass int, mypercent double precision, valpercent double precision, valclass double precision); 

INSERT INTO temp11 
(t_idx, mydate, myclass, mypercent, valpercent, valclass) VALUES 
(1, '01.01.2014', 1, 10,  10,  1), 
(2, '01.01.2014', 2, 20,  20,  4), 
(3, '01.01.2014', 2, 20,  50,  10), 
(4, '01.01.2014', 1, 10,  17, 1.7), 
(5, '02.01.2014', 2, 20,  40,  8), 
(6, '02.01.2014', 1, 10,  18, 1.8), 
(7, '02.01.2014', 2, 20,  50,  10), 
(8, '03.01.2014', 1, 10,  10,  1), 
(9, '03.01.2014', 2, 20,  40,  8), 
(10, '03.01.2014', 1, 10,  20,  2), 
(11, '03.01.2014', 2, 20,  30,  6); 

现在我有一个分组和总结说成日期和valclasses查询:

SELECT mydate, myclass, mypercent, 
     SUM(valpercent)   AS sumvalpercent, 
     SUM(valclass)   AS sumvalclass, 
     SUM(valpercent+valclass) AS sum_row 
FROM temp11 
GROUP BY mydate, myclass, mypercent 
ORDER BY mydate; 

结果此查询的可期待:

"01.01.2014" 2 20 70 14.0 84.0 
"01.01.2014" 1 10 27 2.7 29.7 
"02.01.2014" 1 10 18 1.8 19.8 
"02.01.2014" 2 20 90 18.0 108.0 
"03.01.2014" 2 20 70 14.0 84.0 
"03.01.2014" 1 10 30 3.0 33.0 

但需求有点扩展。

是否有可能做的PostgreSQL,在同一过程中每次约会后,我得到那个日期内,毕竟数据的垂直SUM,到了最后,数据的SUM所有日期,以便结果是这样的:

"01.01.2014" 2 20 70 14.0 84.0 
"01.01.2014" 1 10 27 2.7 29.7 
         97 16.7 113.7 
"02.01.2014" 1 10 18 1.8 19.8 
"02.01.2014" 2 20 90 18.0 108.0 
         108 19.8 127.8 
"03.01.2014" 2 20 70 14.0 84.0 
"03.01.2014" 1 10 30 3.0 33.0 
         100 17.0 117.0 
         305 53.5 358.5 

如果这是可能的这样(或类似),该查询应该如何显示数据?

回答

2

我能想到的最简单的方法是使用UNION ALL一次获得所有需要的输出。 如果您忽略显示日期(order by子句需要)的事实,则此查询以最简单的方式提供请求的输出。

SELECT mydate, myclass, mypercent, 
     SUM(valpercent)   AS sumvalpercent, 
     SUM(valclass)   AS sumvalclass, 
     SUM(valpercent+valclass) AS sum_row 
FROM temp11 
GROUP BY mydate, myclass, mypercent 
UNION ALL 
SELECT mydate || ' total', null, null, 
     SUM(valpercent)   AS sumvalpercent, 
     SUM(valclass)   AS sumvalclass, 
     SUM(valpercent+valclass) AS sum_row 
FROM temp11 
GROUP BY mydate 
UNION ALL 
SELECT 'Total', null, null, 
     SUM(valpercent)   AS sumvalpercent, 
     SUM(valclass)   AS sumvalclass, 
     SUM(valpercent+valclass) AS sum_row 
FROM temp11 
ORDER BY mydate; 

这里有一个fiddle

也许可以更优雅的使用WITH

编辑被改写:

这将是更有效,因为它只能通过temp11表遍历一次。然后它只使用临时表temp100,其中附加总计(每天不超过一行)的行数少得多。 UNION仍然存在,逻辑仍然相同。

WITH temp100 (mydate,myclass,mypercent, sumvalpercent,sumvalclass,sum_row) as (
    SELECT mydate, myclass, mypercent, 
     SUM(valpercent)   AS sumvalpercent, 
     SUM(valclass)   AS sumvalclass, 
     SUM(valpercent+valclass) AS sum_row 
    FROM temp11 
    GROUP BY mydate, myclass, mypercent 
) 
SELECT mydate,myclass,mypercent, sumvalpercent,sumvalclass,sum_row 
FROM temp100 
UNION ALL 
SELECT mydate || ' total' as mydate, null, null, SUM(sumvalpercent), SUM(sumvalclass), SUM(sum_row) 
FROM temp100 
GROUP BY mydate 
UNION ALL 
SELECT 'Total' as mydate, null, null, SUM(sumvalpercent), SUM(sumvalclass), SUM(sum_row) 
FROM temp100 
ORDER BY mydate; 

这是fiddle

+0

感谢foibs,给出了可预期的结果和“刷新”在希望的顺序完全有序outpud为容易从制作HTML报告。如果你可以给予更优雅的解决方案,我会很高兴,但给一个很好的。 –

+0

@ user973238我添加了另一个应该更快的选择,特别是如果你有很多数据。欢呼 – foibs

+0

这里是大数据不能预期,但感谢您的额外解决方案。它将用于教育目的。 –