查询多个Postgres表

时间:2017-09-10 04:08:50

标签: sql postgresql

我有一个查询,我想对多个表,然后在最后加入结果。

这很有效,但我希望有更简洁的方法来实现同样的目标

SELECT key, a.c as "TableA count", b.c as "TableB count", c.c as "TableC count", d.c as "TableD count"
FROM
(
    SELECT key, count(key) as c
    FROM table_a
    WHERE data = 'foo'
    GROUP BY key
) a
FULL OUTER JOIN
(
    SELECT key, count(key) as c
    FROM table_b
    WHERE data = 'foo'
    GROUP BY key
) b USING(key)
FULL OUTER JOIN
(
    SELECT key, count(key) as c
    FROM table_c
    WHERE data = 'foo'
    GROUP BY key
) c USING(key)
FULL OUTER JOIN
(
    SELECT key, count(key) as c
    FROM table_d
    WHERE data = 'foo'
    GROUP BY key
) d USING(key);

预期产出:

 key |  A count |  B count | C  count |  D count |
-----+----------+----------+----------+----------+
5740 |        5 |      102 |      129 |          |
5741 |     1017 |    22163 |    34888 |      218 |
5742 |      797 |    10846 |    19285 |      159 |
5743 |    24966 |   398067 |   572504 |     4772 |
5744 |    31942 |   278944 |    73628 |     5665 |
5745 |     3975 |    54322 |    98578 |     1103 |
5746 |     1353 |     4751 |    33129 |      259 |

1 个答案:

答案 0 :(得分:1)

我认为,如果您使用key加入表格,那是因为key位于同一个域中(至少在概念上是这样)。

如果您拥有或可能拥有key中所有PK值的表格,那么您可以做得更好。

部分解决方案

仅当key是表格的主键

SELECT key, total_a, total_b, total_c, total_d
   FROM key_table, 
        lateral (
          SELECT count(key) as total_a
          FROM table_a
          WHERE key = key_table.key AND data = 'foo'
        ) a,
        lateral (
          SELECT count(key) as total_b
          FROM table_b
          WHERE key = key_table.key AND data = 'foo'
        ) b,
        lateral (
          SELECT count(key) as total_c
          FROM table_c
          WHERE key = key_table.key AND data = 'foo'
        ) c,
        lateral (
          SELECT count(key) as total_d
          FROM table_d
          WHERE key = key_table.key AND data = 'foo'
        ) d
    WHERE total_a IS NOT NULL OR total_b IS NOT NULL OR  total_c IS NOT NULL OR  total_d IS NOT NULL
    ORDER BY key

更改模型解决方案

其他解决方案是在同一个表中更改具有table_Ls数据的数据模型。对于现有查询,您可以拥有视图。如果table_L表位于同一个域(例如不同国家/地区的城市)并且列相同(或具有最小差异),则这是一个很好的解决方案。

新表格必须包含值为source_data的新字段'a', 'b', 'c', d',并且四个视图如下:

 CREATE VIEW table_a AS 
   SELECT key, foo, others_field1, other_field2, ...
     FROM table_abcd
     WHERE source_data = 'a'
   WITH CHECK OPTION;

这样做你可以做类似的事情。主要问题是table_L表的外键,如果你有,你可以对相关表做同样的事情。

查看https://www.postgresql.org/docs/current/static/sql-createview.html#SQL-CREATEVIEW-UPDATABLE-VIEWS

将数据触发到另一个表

如果表位于不同的域中,并且此查询非常重要,则可以在anohter表中触发该数据。例如,key是添加数据的人的用户名(并且您希望为此付费),而table_L是非常不同的东西。

您可以为每个table_L表添加一个触发器,以触发对包含所需字段(包括recolected_data字段)的其他表source_table的更新,然后使用简单的group by查询进行查询。