mysql - 优化联盟请求

标签 mysql join optimization union

我使用 SQL。 我有两张 table

表 1: ID、thing_name、thing_code、thing_localization

表 2: ID、thing_id、thing_value_1、thing_value_2、eval_year、eval_month、T1_ID

表 1 包含一些内容。事物有名称、代码和本地化。表2包含与事物的不同评价相对应的条目。每月进行一次评估。 我们不会每个月评估每件事,所以我们有一些事情不是每个月评估

我想做什么?

我想要:

1) 我希望在特定年份(Y 年)开始之前对与名为“LOCAL_0”的特定本地相关的每件事进行评估总和。 相应的 SQL 查询如下所示:

SELECT T.thing_code, SUM(E.thing_eval_1), SUM(E.thing_eval_2)
FROM table1 T, table2 E
WHERE T.ID = E.T1_ID AND T.thing_localisation = "LOCAL_0" AND E.eval_year < y

2) 我想要对从 y 年初到 y 月 m 月底完成的事物(与 LOCAL_0 相关)的评估总和。 SQL 查询如下所示:

SELECT T.thing_code, SUM(E.thing_eval_1), SUM(E.thing_eval_2)
FROM table1 T, table2 E
WHERE T.ID = E.T1_ID AND T.thing_localisation = "LOCAL_0"
AND E.eval_year = y and E.eval_month <= m

第一个查询的结果如下所示

+------------------------------------------------------+
| thing_code    SUM_EVAL_1_BEFORE    SUM_EVAL 2_BEFORE |
+------------------------------------------------------+
| 111           1                    2                 |
| 112           3                    4                 |
| 113           5                    6                 |
+------------------------------------------------------+

第二个查询的结果如下所示

+-----------------------------------------------+
| thing_code    SUM_EVAL_1_NOW   SUM_EVAL_2_NOW |
+-----------------------------------------------+
| 110           0.5              0.3            |
| 111           0.1              0.1            |
| 112           1                0.9            |
+-----------------------------------------------+

3)我想最终构建一个给我这个结果的请求

+--------------------------------------------------------------------------+
| thing_code EVAL_1_BEF EVAL_2_BEF EVAL_1_NOW EVAL_2_NOW EVAL_1_NOW E2_NOW |
+--------------------------------------------------------------------------+
| 110        0          0          0.5        0.3        0.5        0.3    |
| 111        1          2          0.1        0.1        1.1        2.1    |
| 112        3          4          1          0.9        4          4.9    |
| 113        5          6          0          0          5          6      |
+--------------------------------------------------------------------------+

为此,我进行了搜索,发现了一个运行良好的请求,但我花了太长时间才给出结果(因为数据库确实很大,有很多条目,数百万行)

SELECT UN.code,
       UN.Eval1_BEF,
       UN.Eval2_BEF,
       UN.Eval1_NOW,
       UN.Eval2_NOW,
       (UN.Eval1_BEF + UN.Eval1_NOW) AS Eval1_AFTER,
       (UN.Eval2_BEF + UN.Eval2_NOW) AS Eval2_AFTER

FROM
(
SELECT R1.thing_code AS code, R1.Eval1 AS Eval1_BEF, R1.Eval2 AS Eval2_BEF, R2.Eval1 AS Eval1_NOW, R2.Eval2 AS Eval2_NOW
FROM Result_Request_1 R1 LEFT JOIN Result_Request_2 R2 ON R1.thing_code = R2.thing code

UNION

SELECT R2.thing_code AS code, R1.Eval1 AS Eval1_BEF, R1.Eval2 AS Eval2_BEF, R2.Eval1 AS Eval1_NOW, R2.Eval2 AS Eval2_NOW
FROM Result_Request_1 R1 RIGHT JOIN Result_Request_2 R2 ON R1.thing_code = R2.thing code

) UN

ORDER BY UN.code;

我想优化这个请求,因为它花费的时间太长。谁能帮我?抱歉我的英语不好......

最佳答案

使用条件聚合:

SELECT
    T.thing_code,
    SUM(CASE WHEN E.eval_year < y THEN E.thing_eval_1 ELSE 0 END) AS SUM_EVAL_1_BEFORE,
    SUM(CASE WHEN E.eval_year < y THEN E.thing_eval_2 ELSE 0 END) AS SUM_EVAL_2_BEFORE,
    SUM(CASE WHEN E.eval_year = y and E.eval_month <= m
             THEN E.thing_eval_1 ELSE 0 END) AS SUM_EVAL_1_NOW,
    SUM(CASE WHEN E.eval_year = y and E.eval_month <= m
             THEN E.thing_eval_2 ELSE 0 END) AS SUM_EVAL_2_NOW
FROM table1 T
INNER JOIN table2 E
    ON T.ID = E.T1_ID
WHERE
    T.thing_localisation = 'LOCAL_0'
GROUP BY
    T.thing_code;

关于mysql - 优化联盟请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52035840/

相关文章:

php - 从三个表中进行 SQL SELECT,并在投票系统中进行排序

sql - 如何从一个JOIN返回多个记录作为列?

c++ - 优化嵌套 C++ 循环中的乘法器

java - switch 中计算的 case 语句 (java)

php - Laravel 5多个图像上传到表单内并将img位置保存在数据库中

c# - 如何将sql多个LEFT JOIN转换为linq

mysql - 连接2个mysql表时如何仅获取第二个表中所需的相关行

algorithm - 产业划分问题

mysql - 限制 MySQL 重复

PHP 应用程序无法与某些 MYSQL 数据库通信