汇总来自不同表的数据

时间:2018-07-24 11:09:42

标签: sql postgresql

我坚持尝试一些东西。

如下所示,我有那些表(应用程序,版本,记录,record_version_application,历史记录)

记录表包含每个活动记录。 历史记录包含非活动记录,并保留已编辑记录的历史记录。

我正在使用Postgresql 10

表格应用和版本:

+---------------------+-----------------------------+-----------------------+
|  Table Application  |                             |     Table version     |
+---------------------+-----------------------------+-----------------------+
| ip_app | nom_app    |                             | id_version | version  |
+--------+------------+-----------------------------+------------+----------+
| 10     | ABC        |                             | 4          | 1.0.0.1  |
+--------+------------+-----------------------------+------------+----------+
| 13     | DEF        |                             | 5          | 1.2.0.1  |
+--------+------------+-----------------------------+------------+----------+
| 20     | GHI        |                             | 6          | 1.0.0.1  |
+--------+------------+-----------------------------+------------+----------+
| 28     | JKL        |                             | 7          | 2.2.2.2  |
+--------+------------+-----------------------------+------------+----------+
|        |            |                             | 8          | 2.2.2.3  |
+--------+------------+-----------------------------+------------+----------+
|        |            |                             | 9          | 1.1.1.1  |
+--------+------------+-----------------------------+------------+----------+

表记录:

+-----------+------------+-----------+
| id_record | start_date | end_date  |
+-----------+------------+-----------+
| 5         | 2018-7-10  | 2018-7-12 |
+-----------+------------+-----------+
| 9         | 2018-7-15  | 2018-7-18 |
+-----------+------------+-----------+
| 10        | 2018-7-20  | 2018-7-30 |
+-----------+------------+-----------+

表record_version_application

+-----------+------------+----------------+
| id_record | id_version | id_application |
+-----------+------------+----------------+
| 5         | 1.0.0.1    | 4              |
+-----------+------------+----------------+
| 9         | 1.2.0.1    | 8              |
+-----------+------------+----------------+
| 10        | 1.0.0.1    | 9              |
+-----------+------------+----------------+

表格历史记录:

+------------+-----------+--------+---------+------------+-----------+
| id_history | id_record | id_app | version | start_date | end_date  |
+------------+-----------+--------+---------+------------+-----------+
| 9          | 2         | 10     | 1.0.0.0 | 2017-6-25  | 2017-7-30 |
+------------+-----------+--------+---------+------------+-----------+
| 10         | 5         | 10     | 1.0.0.1 | 2018-7-15  | 2018-7-10 |
+------------+-----------+--------+---------+------------+-----------+
| 11         | 10        | 20     | 1.2.0.1 | 2018-7-18  | 2018-7-28 |
+------------+-----------+--------+---------+------------+-----------+
| 12         | 1         | 13     | 2.2.2.2 | 2018-5-10  | 2018-5-16 |
+------------+-----------+--------+---------+------------+-----------+
| 13         | 9         | 13     | 2.2.2.3 | 2018-7-5   | 2018-7-8  |
+------------+-----------+--------+---------+------------+-----------+
| 14         | 9         | 13     | 2.2.2.3 | 2018-7-12  | 2018-7-18 |
+------------+-----------+--------+---------+------------+-----------+
| 15         | 3         | 28     | 1.1.1.1 | 2018-7-12  | 2018-7-15 |
+------------+-----------+--------+---------+------------+-----------+
| 16         | 3         | 28     | 1.1.1.1 | 2018-8-12  | 2018-8-20 |
+------------+-----------+--------+---------+------------+-----------+

第一个提取结果应该是两个表之间的UNION查询。 如果两个表中都存在[id_app / version]对,则应仅将其保留在记录表中。

如果“历史记录”表中有许多相同的[id_app / version]对,则应仅保留最后一个(也应该是数据库中插入的最后一个)。

第一个提取结果将是这样的:

+--------+---------+------------+-----------+
| id_app | version | start_date | end_date  |
+--------+---------+------------+-----------+
| 10     | 1.0.0.0 | 2017-6-25  | 2017-7-30 |
+--------+---------+------------+-----------+
| 10     | 1.0.0.1 | 2018-7-10  | 2018-7-12 |
+--------+---------+------------+-----------+
| 20     | 1.2.0.1 | 2018-7-20  | 2018-7-30 |
+--------+---------+------------+-----------+
| 13     | 2.2.2.2 | 2018-5-10  | 2018-5-16 |
+--------+---------+------------+-----------+
| 13     | 2.2.2.3 | 2018-7-15  | 2018-7-18 |
+--------+---------+------------+-----------+
| 28     | 1.1.1.1 | 2018-8-12  | 2018-8-20 |
+--------+---------+------------+-----------+

最终结果应该是使用array_agg(Postgresql)由id_app分组的上一个结果的合计结果

最终的期望结果将是:

+--------+--------------------+------------------------+------------------------+
| name_app| version            | start_date             | end_date               |
+--------+--------------------+------------------------+------------------------+
| ABC    | [1.0.0.0, 1.0.0.1] | [2017-6-25, 2018-7-10] | [2017-7-30, 2018-7-12] |
+--------+--------------------+------------------------+------------------------+
| GHI    | [1.2.0.1]          | [2018-7-18]            | [2018-7-28]            |
+--------+--------------------+------------------------+------------------------+
| DEF    | [2.2.2.2, 2.2.2.3] | [2018-5-10, 2018-7-15] | [2018-5-16, 2018-7-18] |
+--------+--------------------+------------------------+------------------------+
| JKL    | [1.1.1.1]          | [2018-8-12]            | [2018-8-20]            |
+--------+--------------------+------------------------+------------------------+

请注意,开始日期,结束日期也可以为NULL

我只能意识到其中的一部分仅依赖于记录表而不是历史记录

SELECT a.name_app, array_to_json(array_agg(v.version ORDER BY version)) AS version, 
array_to_json(array_agg(to_char(start_date, 'DD Mon YYYY') ORDER BY version)) AS start_date, 
array_to_json(array_agg(to_char(end_date, 'DD Mon YYYY') ORDER BY version)) AS end_date
        FROM record r NATURAL JOIN record_application_version NATURAL JOIN version v NATURAL JOIN application a
        GROUP BY nom_app
        ORDER BY nom_app;

我只能同时使用“记录”和“历史记录”表。

我一直在使用并尝试以下操作:

如果您有任何可以帮助我实现这一目标的技巧,我将不胜感激。 此外,如果您还有其他建议,我会很乐意接受。

谢谢

PS:英语不是我的母语。如果不清楚,请告诉我。

1 个答案:

答案 0 :(得分:0)

在两个表A和B之间构造一个并集C,其中C包含A的每一行和不在A中的B的行。

具有记录,版本,应用程序,record_application_version的JOIN表 和B历史记录表。

我已经通过WHERE NOT EXISTS查询解决了我的问题,

SELECT * FROM A
UNION
SELECT * FROM B R1
    WHERE NOT EXISTS
        SELECT * FROM A
            WHERE A.value = B.value;
    AND NOT EXISTS 
    (SELECT * FROM R2
         WHERE R1.date_value < R2.date_value AND R1.id_app = R2.id_app);