あなたは、単に二つのテーブルの和集合を生成し、そのメッセージは、集計関数でカウント追加me
とfriends
のグループの組み合わせにGROUP BY
を使用することができます。
SELECT me, friends, sum(count) AS messages_total
FROM (
SELECT me, friends, messages_sent AS count FROM Table1
UNION ALL
SELECT me, friends, messages_received FROM Table2
) AS t
GROUP BY me, friends;
編集:私は約ました私の答えを編集して、パトリックの答えをより良いものとして推薦するノートを追加するが、私は単純なベンチマークを実行するのが楽しいと決めた。だから我々は次のセットアップ(各テーブルに100万行)がある場合:次に、第一の溶液
CREATE TABLE table1 (
me integer not null,
friends integer not null,
messages_sent integer not null
);
CREATE TABLE table2 (
me integer not null,
friends integer not null,
messages_received integer not null
);
INSERT INTO table1 SELECT n1, n2, floor(random()*10)::integer FROM generate_series(1, 1000) t1(n1), generate_series(1, 1000) t2(n2);
INSERT INTO table2 SELECT n1, n2, floor(random()*10)::integer FROM generate_series(1, 1000) t1(n1), generate_series(1, 1000) t2(n2);
CREATE INDEX ON table1(me, friends);
CREATE INDEX ON table2(me, friends);
ANALYZE;
:
$ EXPLAIN ANALYZE
SELECT me, friends, sum(count) AS messages_total
FROM (
SELECT me, friends, messages_sent AS count FROM Table1
UNION ALL
SELECT me, friends, messages_received FROM Table2
) AS t
GROUP BY me, friends;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------
HashAggregate (cost=45812.00..46212.00 rows=40000 width=12) (actual time=1201.602..1499.285 rows=1000000 loops=1)
Group Key: table1.me, table1.friends
-> Append (cost=0.00..30812.00 rows=2000000 width=12) (actual time=0.022..299.260 rows=2000000 loops=1)
-> Seq Scan on table1 (cost=0.00..15406.00 rows=1000000 width=12) (actual time=0.020..91.357 rows=1000000 loops=1)
-> Seq Scan on table2 (cost=0.00..15406.00 rows=1000000 width=12) (actual time=0.004..77.672 rows=1000000 loops=1)
Planning time: 0.255 ms
Execution time: 1529.642 ms
そして、第二の溶液:だから驚くほど
$ EXPLAIN ANALYZE
SELECT me, friends,
coalesce(messages_sent, 0) + coalesce(messages_received, 0) AS messages_total
FROM Table1
FULL JOIN Table2 USING (me, friends)
ORDER BY me;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------
Sort (cost=219582.13..222082.13 rows=1000000 width=24) (actual time=1501.873..1583.915 rows=1000000 loops=1)
Sort Key: (COALESCE(table1.me, table2.me))
Sort Method: external sort Disk: 21512kB
-> Merge Full Join (cost=0.85..99414.29 rows=1000000 width=24) (actual time=0.074..912.598 rows=1000000 loops=1)
Merge Cond: ((table1.me = table2.me) AND (table1.friends = table2.friends))
-> Index Scan using table1_me_friends_idx on table1 (cost=0.42..38483.49 rows=1000000 width=12) (actual time=0.039..165.772 rows=1000000 loops=1)
-> Index Scan using table2_me_friends_idx on table2 (cost=0.42..38483.49 rows=1000000 width=12) (actual time=0.018..194.177 rows=1000000 loops=1)
Planning time: 1.091 ms
Execution time: 1615.011 ms
を、 FULL JOIN
のソリューションは、インデックスを利用することはできますが、少し悪化します。私はこれが完全な結合と関係していると思います。他のタイプの参加については、はるかに良いでしょう。
PostgreSQLを使用している場合は、MySQLタグを使用しないでください。 – Barmar