2011-03-02 9 views
5

aynı sütunları ile iki tablo var ekleyin aynı sütun adları ile iki tablo birleştirme, birinci sütun adıdır ve ikinci sayısıdır. Her isim iki tablo katma sayısı ile görünecek şekilde, bu tabloları birleştirmek istiyorum: Ben bu yürütmek için oldukça çirkin bir yapı oluşturduk an itibariylesayaçları

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 

ve eğer öğrenmek istiyorum sonuçları daha zarif bir şekilde almak mümkündür. Bugüne kadar ne var

(Tablo 1 test1 olduğunu ve Table2 test2 edilir):

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; 

cevap

11
=> 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) 
+1

teşekkürler, sadece "X" in ne olduğunu anlamaya çalışıyorum? belgelerinde bulamıyorum. – evgeni

+2

X bir masa takma addır (Google bunun için). Bu durumda, tablo aslında bir alt sorgudan oluşan bir tablo ifadesidir. PostgreSQL ve MySQL (en azından) alt sorguların adlandırılmasını gerektirir. Açıklama, 'select X.name, sum (X.cnt) ...' şeklinde yazılmıştır. Ancak, takma adını kullanmadığımdan, sadece bir kukla isim vereceğim. – Reece

8

şuna ne dersiniz, saf SQL: Temelde biz tam dış yapıyoruz

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; 

katılmak İki tabloyu birleştirmek için ad alanında. Zor olan bölüm, tam dış birleştirme ile, bir tabloda bulunan ancak diğerinin bulunmadığı satırlar görünecektir, ancak diğer tabloda NULL olacak; t1 "name1" e sahipse, ancak t2 yoksa, join bize t2.name ve t2.name için NULL verir.

BIRLEŞIM fonksiyonu olmayan ilk NULL argüman döner, bu yüzden BOŞ 0'a sayar "dönüştürmek" için ve doğru tablodan adını almak için kullanabilirsiniz. Bu Wayne'deki bahşiş için teşekkürler!

İyi şanslar!

+2

senin sandığın şey kaynaşabilecek işlevi var mı? örneğin, 'COALESCE (t1.name, t2.name) ',' COALESCE (t1.count, 0) + COALESCE (t2.count, 0)'. –

+0

Evet, bu o! –

+5

Ayrıca, Postgresql'de birleştirme koşulunu basitçe '' USING (isim) 'olarak yazabilir ve daha sonra basitçe sütun listesine' isim 'yazabilirsin: 'SELECT name, ... FROM T1 DIŞI OUTER JOIN t2 KULLANIMI (isim)' – araqnid

0

alternatif bir yöntem, adı tablolar İLE SUM (miktar) ve GRUP kombine JOIN DOĞAL tam dış kullanmaktır. Aşağıdaki SQL kodunu tam olarak arzu edilen sonucu verir:

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 

yapay Tableıd kolon DOĞAL TAM DIŞ artır sağlar t1 her satır için ve t2 her satır için ayrı bir satır oluşturur. Diğer bir deyişle, ara sonuçta "isim3, 3" ve "isim4, 4" satırları iki kez görünür. Bu yinelenen satırları birleştirmek ve sayıları toplamak için satırları ad sütununa göre gruplayabilir ve sayı sütununu toplayabiliriz.

İlgili konular