通过在不同列上执行多个总和来创建视图

时间:2017-04-05 21:04:06

标签: mysql sql

我的MYSQL数据库中有两个表,我需要在视图中合并它们。 在这两张桌子上我必须进行一些数学计算才能得到正确的结果,我必须在同一天订购它们。

第一个表格与下面的表格类似,称为chiusure

+----+------------+--------+--------+---------+------+----+
| id | data       | totale | sconti | annulli | resi | sf |
+----+------------+--------+--------+---------+------+----+
|  1 | 2016-03-01 | 153.82 |   1.07 |    0.00 | 0.00 | 34 |
|  2 | 2016-03-02 | 241.58 |   0.01 |    0.00 | 0.00 | 32 |
|  3 | 2016-03-03 |   0.00 |   0.01 |    0.00 | 0.00 |  0 |
|  4 | 2016-03-04 |   0.00 |   0.00 |    0.00 | 0.00 |  0 |
|  5 | 2016-03-05 |   0.00 |   0.00 |    0.00 | 0.00 |  0 |
+----+------------+--------+--------+---------+------+----+

第二个表格与下面的表格类似,称为emergenza

+----+------------+----------+--------+
| id | data       | ora      | totale |
+----+------------+----------+--------+
|  1 | 2016-03-04 | 09:30:00 |   2.20 |
|  2 | 2016-03-04 | 09:40:00 |   9.00 |
|  3 | 2016-03-04 | 09:50:00 |   5.00 |
|....|............|..........|........|
| 27 | 2016-03-05 | 09:14:00 |   4.40 |
| 28 | 2016-03-05 | 09:27:00 |   5.00 |
| 29 | 2016-03-05 | 09:33:00 |   2.20 |
|....|............|..........|........|
+----+------------+----------+--------+

我觉得这里很困难的是,emergenza表中有多行具有相同的日期。在另一个视图(view_emergenza)中,我按照这种方式按日期对它们进行了分组:

SELECT
    data,
    sum(totale) AS chiusura,
    count(id) AS sf

FROM emergenza

GROUP BY DAY(data);

结果是:

+------------+----------+----+
| data       | chiusura | sf |
+------------+----------+----+
| 2016-03-04 |   178.90 | 26 |
| 2016-03-05 |   330.55 | 52 |
| 2016-03-06 |   333.55 | 46 |
| 2016-03-07 |   272.40 | 31 |
| 2016-03-08 |   169.40 | 28 |
| 2016-03-09 |   223.40 | 20 |
| 2016-03-10 |   206.00 | 19 |
| 2016-03-11 |   157.50 | 22 |
+------------+----------+----+

此外,我需要在总结两个表之前执行一些数学运算。在一个视图(view_chiusure)中,我进行了这种数学运算以达到想要的结果:

SELECT data, (totale - annulli - resi) AS chiusura, sf
    FROM chiusure

结果是:

+------------+----------+----+
| data       | chiusura | sf |
+------------+----------+----+
| 2016-03-01 |   153.82 | 34 |
| 2016-03-02 |   241.58 | 32 |
| 2016-03-03 |     0.00 |  0 |
| 2016-03-04 |     0.00 |  0 |
| 2016-03-05 |     0.00 |  0 |
+------------+----------+----+

此时我想在一个独特的视图中合并两个视图:

  • GROUP BY DAY(数据)AS数据
  • (chiusure.totale - chiusure.annulli - chiusure.resi)+ [sum(emergenza.totale)GROUP BY emergenza.data WHERE emergenza.data = chiusure.data]
  • chiusure.sf + [count(emergenza.id)GROUP BY emergenza.data WHERE emergenza.data = chiusure.data]

更新

我试着这样:

SELECT
        C.data,
        C.chiusura + (SELECT E.chiusura FROM view_emergenza E WHERE E.data = C.data ) AS chiusura,
        C.sf + (SELECT E.sf FROM view_emergenza E WHERE E.data = C.data ) as sf
    FROM view_chiusure C

但似乎完全忽略了view_chiusure.chiusuraview_chiusure.sf

+------------+----------+------+
| data       | chiusura | sf   |
+------------+----------+------+
| 2016-03-01 |     NULL | NULL |
| 2016-03-02 |     NULL | NULL |
| 2016-03-03 |     NULL | NULL |
| 2016-03-04 |   178.90 |   26 |
| 2016-03-05 |   330.55 |   52 |
| 2016-03-06 |   333.55 |   46 |
| 2016-03-07 |   272.40 |   31 |
| 2016-03-08 |   169.40 |   28 |
| 2016-03-09 |   223.40 |   20 |
| 2016-03-10 |   206.00 |   19 |
+------------+----------+------+

结果应为

+------------+----------+------+
| data       | chiusura | sf   |
+------------+----------+------+
| 2016-03-01 |   153.82 |   34 |
| 2016-03-02 |   241.58 |   42 |
| 2016-03-03 |     0.00 |    0 |
| 2016-03-04 |   178.90 |   26 |
| 2016-03-05 |   330.55 |   52 |
| 2016-03-06 |   333.55 |   46 |
| 2016-03-07 |   272.40 |   31 |
| 2016-03-08 |   169.40 |   28 |
| 2016-03-09 |   223.40 |   20 |
| 2016-03-10 |   206.00 |   19 |
+------------+----------+------+

是否可以将两个表合并和求和?如果是,我该怎么做?

3 个答案:

答案 0 :(得分:0)

您需要为联合中的每个选择添加一个人工列,以防止丢失匹配的行。

假设你选择了2个你想要聚合的工作,那么这应该有效:

select 'data' as data, 
       sum(chiusura) as chiusura, 
       sum(sf) as sf from
(
    SELECT 1 as col, chiusure.`data`, (chiusure.totale - chiusure.annulli - chiusure.resi) AS chiusura, chiusure.sf
    FROM chiusure

    UNION
    SELECT 2 as col, emergenza.`data`, emergenza.totale as chiusura, count(emergenza.id) as sf
    FROM emergenza
) tables
group by 'data'

答案 1 :(得分:0)

您必须首先创建观看次数view_emergenzaview_chiusure。 然后,您必须创建一个视图以仅获取日期:

CREATE VIEW vu_data AS
  (
  SELECT data FROM view_chiusure
  UNION
  SELECT data FROM view_emergenza
  )

然后创建一个视图以获取不同的日期:

CREATE VIEW vu_distinct_data AS
  SELECT DISTINCT data
  FROM vu_data

现在您可以创建另一个视图来加入基本视图,如下所示:

CREATE VIEW vu_join AS
  SELECT
    (SELECT C.chiusura FROM view_chiusura C WHERE C.data=D.data)+
    (SELECT E.chiusura FROM view_emergenza E WHERE E.data=D.data) AS chiusura,
    (SELECT C.sf FROM view_chiusura C WHERE C.data=D.data)+
    (SELECT E.sf FROM view_emergenza E WHERE E.data=D.data) AS sf,
    D.data
  FROM vu_distinct_data D

现在您可以轻松使用vu_join

SELECT *
FROM vu_join
ORDER BY data

答案 2 :(得分:0)

这个问题的解决方案非常复杂,但我一直在寻找解决了这个问题的ESISTSCASE

解决方案是:

SELECT
        C.data,
        (
            CASE
                WHEN
                    EXISTS (SELECT E.chiusura FROM view_emergenza E WHERE E.data = C.data) = 1
                        THEN (SELECT E.chiusura FROM view_emergenza E WHERE E.data = C.data)
                ELSE 0
            END
        )
        + C.chiusura AS chiusura
    FROM view_chiusure C

在上述解决方案中,view_emergenza将覆盖view_chiusure,而不是对两个表进行求和。这对我来说仍然不清楚。

EXISTS 检查查询是否返回某个值。由于 EXISTS 返回布尔值(true,false; 1,0),我必须检查该行是否匹配。这里有 CASE 帮助。

因此,如果行匹配,它将执行 SELECT 并返回所需的值, ELSE 它必须返回0。

最终我会将结果添加到第一个表列。

结果如下:

+------------+----------+
| data       | chiusura |
+------------+----------+
| 2016-03-01 |   153.82 |
| 2016-03-02 |   241.58 |
| 2016-03-03 |     0.00 |
| 2016-03-04 |   178.90 |
| 2016-03-05 |   330.55 |
+------------+----------+

为了进行一些测试,我更新了原始表chiusure

UPDATE chiusure SET totale = 50 WHERE data = "2016-03-04";

最初是0。

+----+------------+--------+--------+---------+------+----+
| id | data       | totale | sconti | annulli | resi | sf |
+----+------------+--------+--------+---------+------+----+
|  1 | 2016-03-01 | 153.82 |   1.07 |    0.00 | 0.00 | 34 |
|  2 | 2016-03-02 | 241.58 |   0.01 |    0.00 | 0.00 | 32 |
|  3 | 2016-03-03 |   0.00 |   0.01 |    0.00 | 0.00 |  0 |
|  4 | 2016-03-04 |  50.00 |   0.00 |    0.00 | 0.00 |  0 |
|  5 | 2016-03-05 |   0.00 |   0.00 |    0.00 | 0.00 |  0 |
+----+------------+--------+--------+---------+------+----+

view_emergenza仍然是一样的:

+------------+----------+----+
| data       | chiusura | sf |
+------------+----------+----+
| 2016-03-04 |   178.90 | 26 |
| 2016-03-05 |   330.55 | 52 |
| 2016-03-06 |   333.55 | 46 |
| 2016-03-07 |   272.40 | 31 |
| 2016-03-08 |   169.40 | 28 |
+------------+----------+----+

然后在新视图中结果是:

+------------+----------+
| data       | chiusura |
+------------+----------+
| 2016-03-01 |   153.82 |
| 2016-03-02 |   241.58 |
| 2016-03-03 |     0.00 |
| 2016-03-04 |   228.90 |
| 2016-03-05 |   330.55 |
+------------+----------+

同样适用于 sf 列。