2011-03-02 16 views
5

जोड़ें मेरे पास दो कॉलम समान कॉलम हैं, पहला कॉलम नाम है और दूसरा एक गिनती है। मैं इन तालिकाओं विलय करने के लिए, ताकि प्रत्येक नाम दो तालिकाओं का जोड़ा गिनती के साथ प्रकट होता है करना चाहते हैं:समान कॉलम नामों के साथ दो तालिकाओं को मर्ज करें, काउंटर

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 

पल मैं इस पर अमल करने के लिए एक बहुत बदसूरत संरचना बनाया है के रूप में, और अगर जानना चाहते हैं परिणामों को एक और अधिक सुरुचिपूर्ण तरीके से प्राप्त करना संभव है।

क्या मैं अब तक है (Table1 test1 है और तालिका 2 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; 

उत्तर

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

धन्यवाद, बस यह पता लगाने की कोशिश कर रहा है कि "एक्स" क्या है? इसे दस्तावेज में नहीं मिल सकता है। – evgeni

+2

एक्स एक टेबल उपनाम है (इसके लिए Google)। इस मामले में, तालिका वास्तव में एक सबक्वायरी से बना एक टेबल अभिव्यक्ति है। PostgreSQL और MySQL (कम से कम) की आवश्यकता है कि subqueries नाम दिया गया है। कथन को 'चयन X.name, योग (X.cnt) ...' के रूप में लिखा जा सकता था। हालांकि, चूंकि मैं उपनाम का उपयोग नहीं करता, इसलिए मैं इसे एक डमी नाम देता हूं। – Reece

8

यह कैसे के बारे में, शुद्ध एसक्यूएल में:

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; 

असल में हम एक पूर्ण बाहरी कर रहे हैं में शामिल होने के दो तालिकाओं को मर्ज करने के लिए नाम फ़ील्ड पर। मुश्किल हिस्सा यह है कि पूर्ण बाहरी शामिल होने के साथ, एक पंक्ति में मौजूद पंक्तियां, लेकिन दूसरी नहीं दिखाई देगी, लेकिन दूसरी तालिका में न्यूल होगा; इसलिए यदि टी 1 में "name1" है लेकिन टी 2 नहीं करता है, तो जुड़ने से हमें t2.name और t2.name के लिए NULLs मिलेंगे।

COALESCE समारोह पहली गैर शून्य तर्क देता है, तो हम इसका इस्तेमाल "कन्वर्ट" शून्य 0 में गिना जाता है और सही मेज से नाम लेने के लिए करने के लिए। इस वेन पर टिप के लिए धन्यवाद!

शुभकामनाएं!

+2

क्या सहकर्मी कार्य है जिसे आप सोच रहे हैं? उदाहरण के लिए, 'coalesce (t1.name, t2.name) ',' coalesce (t1.count, 0) + coalesce (t2.count, 0)'। –

+0

हाँ, वह वही है! –

+5

इसके अलावा, Postgresql में आप के रूप में बस '(नाम) का उपयोग करके शामिल हालत में लिख सकते हैं' और फिर बस स्तंभ सूची में 'name' का संदर्भ लें:,' चयन नाम ... t1 पूर्ण बाहरी से (नाम) का उपयोग t2 शामिल हों ' – araqnid

0

एक वैकल्पिक पद्धति प्राकृतिक पूर्ण बाहरी उपयोग करने के लिए शामिल होने के योग (गिनती) और नाम बयानों द्वारा समूह के साथ संयुक्त है। निम्नलिखित एसक्यूएल कोड वास्तव में पैदावार वांछित परिणाम:

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 

कृत्रिम TableID स्तंभ सुनिश्चित करता है कि प्राकृतिक पूर्ण बाहरी शामिल हों t1 में प्रत्येक पंक्ति के लिए और t2 में प्रत्येक पंक्ति के लिए एक अलग पंक्ति बनाता है। दूसरे शब्दों में, पंक्तियों "name3, 3" और "name4, 4" मध्यवर्ती परिणाम में दो बार दिखाई देते हैं। इन डुप्लिकेट पंक्तियों को मर्ज करने के लिए और गणना करने के लिए हम नाम कॉलम द्वारा पंक्तियों को समूहित कर सकते हैं और गिनती कॉलम को जोड़ सकते हैं।

संबंधित मुद्दे