2016-12-02 50 views
0

我想比較兩個表的所有列值。兩個表是相同的表示列號相同,主鍵相同。任何人都可以建議在postgres中比較這兩個表的查詢。 查詢應該給列名,什麼是二tables.Like這如何比較postgres中每列的兩個相同表格數據?

pkey | column_name | table1_value | table2_value 
123 | bonus  | 1   | 0 
+0

postgres版本?.. –

+0

postgres版本9.6.1 –

回答

1

實例數據的兩個不同的值:

create table test1(pkey serial primary key, str text, val int); 
insert into test1 (str, val) values ('a', 1), ('b', 2), ('c', 3); 

create table test2(pkey serial primary key, str text, val int); 
insert into test2 (str, val) values ('a', 1), ('x', 2), ('c', 33); 

這個簡單的查詢給出了兩個表的區別的完整信息(包括排在他們一人失蹤):

(select 1 t, * from test1 
except 
select 1 t, * from test2) 
union all 
(select 2 t, * from test2 
except 
select 2 t, * from test1) 
order by pkey, t; 

t | pkey | str | val 
---+------+-----+----- 
1 | 2 | b | 2 
2 | 2 | x | 2 
1 | 3 | c | 3 
2 | 3 | c | 33 
(4 rows) 

在Postgres裏9.5+您可以將結果轉用預期格式10:

select pkey, key as column, val[1] as value_1, val[2] as value_2 
from (
    select pkey, key, array_agg(value order by t) val 
    from (
     select t, pkey, key, value 
     from (
      (select 1 t, * from test1 
      except 
      select 1 t, * from test2) 
      union all 
      (select 2 t, * from test2 
      except 
      select 2 t, * from test1) 
     ) s, 
     lateral jsonb_each_text(to_jsonb(s)) 
     group by 1, 2, 3, 4 
    ) s 
    group by 1, 2 
) s 
where key <> 't' and val[1] <> val[2] 
order by pkey; 

pkey | column | value_1 | value_2 
------+--------+---------+--------- 
    2 | str | b  | x 
    3 | val | 3  | 33 
(2 rows) 
0

爲了讓您可以使用所有不同的行:

select * 
from table_1 t1 
    join table_2 t2 on t1.pkey = t2.pkey 
where t1 is distinct from t2; 

這隻會比較存在兩個表中的行。如果你也想找到那些缺少對他們使用全外連接:

select coalesce(t1.pkey, t2.pkey) as pkey, 
     case 
     when t1.pkey is null then 'Missing in table_1' 
     when t2.pkey is null then 'Missing in table_2' 
     else 'At least one column is different' 
     end as status, 
     * 
from table_1 t1 
    full ojoin table_2 t2 on t1.pkey = t2.pkey 
where (t1 is distinct from t2) 
    or (t1.pkey is null) 
    or (t2.pkey is null); 

如果你安裝了hstore擴展,您可以查看不同的鍵/值映射:

select coalesce(t1.pkey, t2.pkey) as pkey, 
     case 
     when t1.pkey is null then 'Missing in table_1' 
     when t2.pkey is null then 'Missing in table_2' 
     else 'At least one column is different' 
     end as status, 
     hstore(t1) - hstore(t2) as values_in_table_1, 
     hstore(t2) - hstore(t1) as values_in_table_2 
from table_1 t1 
    full ojoin table_2 t2 on t1.pkey = t2.pkey 
where (t1 is distinct from t2) 
    or (t1.pkey is null) 
    or (t2.pkey is null); 

採用該試樣數據:

create table table_1 (pkey integer primary key, col_1 text, col_2 int); 
insert into table_1 (pkey, col_1, col_2) 
values (1, 'a', 1), (2, 'b', 2), (3, 'c', 3), (5, 'e', 42); 

create table table_2 (pkey integer primary key, col_1 text, col_2 int); 
insert into table_2 (pkey, col_1, col_2) 
values (1,'a', 1), (2, 'x', 2), (3, 'c', 33), (4, 'd', 52); 

一個可能的結果將是:

pkey | status       | values_in_table_1 | values_in_table_2 
-----+----------------------------------+-------------------+------------------ 
    2 | At least one column is different | "col_1"=>"b"  | "col_1"=>"x"  
    3 | At least one column is different | "col_2"=>"3"  | "col_2"=>"33"  
    4 | Missing in table_1    |     |     
    5 | Missing in table_2    |     |     
0

不怎麼樣,但樂趣和它的工作原理:O)

通過正確的表格和 更新「其中TABLE_SCHEMA =‘公共’和TABLE_NAME =‘MYTABLE1’」

只需更換public.mytable1和public.mytable2
select * from (
    select pkey,column_name,t1.col_value table1_value,t2.col_value table2_value from (
select pkey,generate_subscripts(t,1) ordinal_position,unnest(t) col_value from (
select pkey, 
(
    replace(regexp_replace( -- null fields 
    '{'||substring(a::character varying,'^.(.*).$') ||'}' -- {} instead of () 
,'([\{,])([,\}])','\1null\2','g'),',,',',null,') 
)::TEXT[] t 
from public.mytable1 a 
) a) t1 
left join (
    select pkey,generate_subscripts(t,1) ordinal_position,unnest(t) col_value from (
    select pkey, 
(
    replace(regexp_replace( -- null fields 
    '{'||substring(a::character varying,'^.(.*).$') ||'}' -- {} instead of () 
,'([\{,])([,\}])','\1null\2','g'),',,',',null,') 
)::TEXT[] t 
    from public.mytable2 a 
) a) t2 using (pkey,ordinal_position) 

join (select * from information_schema.columns where table_schema='public' and table_name='mytable1') c using (ordinal_position) 
) final where COALESCE(table1_value,'')!=COALESCE(table2_value,'') 
0

我試了上述所有答案。感謝球員們的幫助。博客之後,我發現一個簡單的查詢。

SELECT <common_column_list> from table1 
EXCEPT 
SELECT <common_column_list> from table2. 

如果有任何table1列值與table2列值不同,它將顯示table1的所有行。

+1

恭喜您成功使用Google!但答案並不符合問題的條件。 – klin

相關問題