HiveBrain v1.2.0
Get Started
← Back to all entries
patternsqlMinor

Understanding a PostgreSQL join

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
postgresqlunderstandingjoin

Problem

I have seen the following query in the PostgreSQL documentation. Unfortunately I don't understand the join criteria.

create temp table tmp_stat_user_tables as select * from pg_stat_user_tables;

select * from pg_stat_user_tables n
join tmp_stat_user_tables t
on n.relid=t.relid
and (n.seq_scan,n.idx_scan,n.n_tup_ins,n.n_tup_upd,n.n_tup_del) <>
(t.seq_scan,t.idx_scan,t.n_tup_ins,t.n_tup_upd,t.n_tup_del);


How I need to understand the JOIN clause?

What the tables are for and what the first query is doing are clear for me.

Solution

I assume:

(n.seq_scan,n.idx_scan,n.n_tup_ins,n.n_tup_upd,n.n_tup_del) <>
(t.seq_scan,t.idx_scan,t.n_tup_ins,t.n_tup_upd,t.n_tup_del)


is what puzzles you. It means that if any of the columns differ the predicate is true. It is a shorter form of:

NOT ( (n.seq_scan,n.idx_scan,n.n_tup_ins,n.n_tup_upd,n.n_tup_del) =
      (t.seq_scan,t.idx_scan,t.n_tup_ins,t.n_tup_upd,t.n_tup_del) )


which in turn can be rewritten as

NOT (  n.seq_scan = t.seq_scan AND
       n.idx_scan = t.idx_scan AND
       ...                          )


not sure if it makes it easier to grasp, but it can also be written using disjunctions

(  n.seq_scan <> t.seq_scan OR
       n.idx_scan <> t.idx_scan OR
       ...                         )


EDIT:

Nulls makes logical reasoning difficult so I created a small example to verify the logical equivalence of the expressions above. I think it is sufficient to use only two variables (http://sqlfiddle.com/#!15/73c52/2):

create table s (x int);
insert into s(x) values (null),(0),(1);
create table t (x int, y int);
insert into t(x,y) select s1.x, s2.x from s s1 cross join s s2;


The following expressions corresponds to the ones I used above:

select (t1.x,t1.y)<>(t2.x,t2.y) as a
     , not( (t1.x,t1.y)=(t2.x,t2.y)) as b
     , not ( t1.x = t2.x and t1.y = t2.y ) as c
     , t1.x <> t2.x or t1.y <> t2.y as d 
from t t1
cross join t t2;

a       b       c       d
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
true    true    true    true
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
true    true    true    true
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
true    true    true    true
(null)  (null)  (null)  (null)
true    true    true    true
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
true    true    true    true
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
true    true    true    true
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
true    true    true    true
true    true    true    true
true    true    true    true
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
true    true    true    true
(null)  (null)  (null)  (null)
false   false   false   false
true    true    true    true
true    true    true    true
true    true    true    true
true    true    true    true
(null)  (null)  (null)  (null)
true    true    true    true
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
true    true    true    true
false   false   false   false
true    true    true    true
true    true    true    true
true    true    true    true
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
true    true    true    true
true    true    true    true
true    true    true    true
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
(null)  (null)  (null)  (null)
true    true    true    true
true    true    true    true
true    true    true    true
true    true    true    true
(null)  (null)  (null)  (null)
false   false   false   false
true    true    true    true
(null)  (null)  (null)  (null)
true    true    true    true
(null)  (null)  (null)  (null)
true    true    true    true
true    true    true    true
true    true    true    true
(null)  (null)  (null)  (null)
true    true    true    true
false   false   false   false

Code Snippets

(n.seq_scan,n.idx_scan,n.n_tup_ins,n.n_tup_upd,n.n_tup_del) <>
(t.seq_scan,t.idx_scan,t.n_tup_ins,t.n_tup_upd,t.n_tup_del)
NOT ( (n.seq_scan,n.idx_scan,n.n_tup_ins,n.n_tup_upd,n.n_tup_del) =
      (t.seq_scan,t.idx_scan,t.n_tup_ins,t.n_tup_upd,t.n_tup_del) )
NOT (  n.seq_scan = t.seq_scan AND
       n.idx_scan = t.idx_scan AND
       ...                          )
(  n.seq_scan <> t.seq_scan OR
       n.idx_scan <> t.idx_scan OR
       ...                         )
create table s (x int);
insert into s(x) values (null),(0),(1);
create table t (x int, y int);
insert into t(x,y) select s1.x, s2.x from s s1 cross join s s2;

Context

StackExchange Database Administrators Q#127606, answer score: 8

Revisions (0)

No revisions yet.