Join two tables with the same column names, add counters

I have two tables with the same columns, the first column is the name, and the second is the counter. I would like to combine these tables so that each name appears with an added number of two tables:

Table1:           Table2:            Result Table:
NAME   COUNT      NAME   COUNT       NAME   COUNT
name1  1          name3  3           name1  1
name2  2          name4  4           name2  2
name3  3          name5  5           name3  6
name4  4          name6  6           name4  8
                                     name5  5
                                     name6  6

At the moment, I have created a rather ugly framework to accomplish this and would like to know if the results can be obtained in a more elegant way.

What I had so far (table 1 is test1, and table2 is test2):

create table test1 ( name varchar(40), count integer);
create table test2 ( name varchar(40), count integer);
create table test3 ( name varchar(40), count integer);
create table test4 ( name varchar(40), count integer);
create table test5 ( name varchar(40), count integer);

insert into test4 (name, count) select *  from test1;
insert into test4 (name, count) select *  from test2;
insert into test3 (name , count) select t1.name, t1.count + t2.count 
from test1 t1 inner join test2 t2 on t1.name = t2.name;
select merge_db(name, count) from test3;
insert into test5 (name, count) (select name, max(count) from test4 group by name);


CREATE FUNCTION merge_db(key varchar(40), data integer) RETURNS VOID AS
    $$ -- souce: http://stackoverflow.com/questions/1109061/insert-on-duplicate-update-postgresql
    BEGIN
        LOOP
            -- first try to update the key
            UPDATE test4 SET count = data WHERE name = key;
            IF found THEN
                RETURN;
            END IF;-- not there, so try to insert the key -- if someone else inserts the same key concurrently,        -- we could get a unique-key failure
            BEGIN
                INSERT INTO test4(name,count) VALUES (key, data);
                RETURN;
            EXCEPTION WHEN unique_violation THEN-- do nothing, and loop to try the UPDATE again
            END;
        END LOOP;
    END;
    $$
    LANGUAGE plpgsql;
+5
source share
3 answers
=> create table t1 (name text,cnt int);
=> create table t2 (name text,cnt int);
=> insert into t1 values  ('name1',1), ('name2',2), ('name3',3), ('name4',4);
=> insert into t2 values  ('name3',3), ('name4',4), ('name5',5), ('name6',6);
=> 

select name,sum(cnt) from 
(select * from t1 
union all 
select * from t2 ) X 
group by name 
order by 1;

 name  | sum 
-------+-----
 name1 |   1
 name2 |   2
 name3 |   6
 name4 |   8
 name5 |   5
 name6 |   6
(6 rows)
+11
source

How about this, in pure SQL:

SELECT
  COALESCE(t1.name, t2.name),
  COALESCE(t1.count, 0) + COALESCE(t2.count, 0) AS count
FROM t1 FULL OUTER JOIN t2 ON t1.name=t2.name;

, . , , , , NULL ; , t1 "1", t2 , NULL t2.name t2.name.

COALESCE , NULL, "" NULL 0 . !

!

+8

NATURAL FULL OUTER JOIN SUM (count) GROUP BY. SQL :

SELECT name, SUM(count) AS count FROM
  ( SELECT 1 AS tableid, * FROM t1 ) AS table1 
NATURAL FULL OUTER JOIN
  ( SELECT 2 AS tableid, * FROM t2 ) AS table2
GROUP BY name ORDER BY name

The artificial tableid column ensures that the NATURAL FULL OUTER JOIN creates a separate row for each row in t1 and for each row in t2. In other words, the strings "name3, 3" and "name4, 4" appear twice in the intermediate result. To combine these repeating rows and summarize the counts, we can group the rows by the name column and summarize the count column.

0
source

All Articles