Thread: FULL JOIN is only supported with merge-joinable join conditions
I try to port application to PostgreSQL 8.1+ The following query runs OK in VFP but causes error in Postgres FULL JOIN is only supported with merge-joinable join conditions How to fix ? Andrus. SELECT ametikoh.Nimetus as ametikoht, Isik.nimi, Isik.eesnimi, koosseis.kogus, COALESCE( iandmed.Kuluobj, koosseis.objekt1) as osakond FROM iandmed FULL JOIN koosseis ON iandmed.ametikoht=koosseis.ametikoht AND iandmed.Kuluobj= koosseis.objekt1 AND iandmed.AmetiKoht is not null JOIN ametikoh ON COALESCE(iandmed.ametikoht,koosseis.ametikoht)= ametikoh.AmetiKoht LEFT JOIN isik ON iandmed.isik=isik.isik WHERE true ORDER BY 1,2 Revelant pars of table structures are: CREATE TABLE iandmed ( reanr integer NOT NULL DEFAULT nextval('iandmed_reanr_seq'::regclass), isik character(10) NOT NULL, miskuup date, plopp date, summavrt numeric(12,2), kuluobj character(10), ametikoht numeric(7), CONSTRAINT iandmed_pkey PRIMARY KEY (reanr) ) ; CREATE TABLE koosseis ( id numeric(7) NOT NULL, ametikoht numeric(7) NOT NULL, objekt1 character(10) NOT NULL, kogus numeric(4) NOT NULL DEFAULT 0, algus date, lopp date, CONSTRAINT koosseis_pkey PRIMARY KEY (id) );
"Andrus" <kobruleht2@hot.ee> writes: > I try to port application to PostgreSQL 8.1+ > The following query runs OK in VFP but causes error in Postgres > FULL JOIN is only supported with merge-joinable join conditions > SELECT > ... > FROM iandmed > FULL JOIN koosseis ON iandmed.ametikoht=koosseis.ametikoht > AND iandmed.Kuluobj= koosseis.objekt1 > AND iandmed.AmetiKoht is not null Uh, can't you just drop the "iandmed.AmetiKoht is not null" condition? It seems redundant considering that "iandmed.ametikoht=koosseis.ametikoht" isn't going to succeed when ametikoht is null. In the long run we should teach hash join to support full-join behavior, which would allow cases like this one to work; but it seems not very high priority, since I've yet to see a real-world case where a non-merge-joinable full-join condition was really needed. (FULL JOIN being inherently symmetric, the join condition should usually be symmetric as well...) regards, tom lane
"Andrus" <kobruleht2@hot.ee> writes: >> I've yet to see a real-world case where a >> non-merge-joinable full-join condition was really needed. > I need to eliminate rows containing null value in left side table in full > join. > create table iandmed ( ametikoht integer ); > insert into iandmed values(1); > insert into iandmed values(null); > create table koosseis (ametikoht integer ); > insert into koosseis values(2); > SELECT * > FROM iandmed > FULL JOIN koosseis ON iandmed.ametikoht=koosseis.ametikoht > AND iandmed.ametikoht IS NOT NULL > Required result: > 1 null > null 2 Well, if we did support that query as written, it would not produce the result you want. With or without the IS NOT NULL part, the null-containing row of iandmed will fail to join to every row of koosseis, and will therefore produce a single output row with nulls for the koosseis field(s). If you get a different result in some other database, it's broken (nonstandard handling of NULL comparison maybe?). I think the way to get the result you want is to suppress the null-containing rows before they get to the FULL JOIN, like so: regression=# SELECT * FROM (SELECT * FROM iandmed WHERE ametikoht IS NOT NULL) AS iandmed FULL JOIN koosseis ON iandmed.ametikoht=koosseis.ametikoht; ametikoht | ametikoht -----------+----------- 1 | | 2 (2 rows) regards, tom lane
> I think the way to get the result you want is to suppress the > null-containing rows before they get to the FULL JOIN, like so: > > regression=# SELECT * > FROM (SELECT * FROM iandmed WHERE ametikoht IS NOT NULL) AS iandmed > FULL JOIN koosseis ON iandmed.ametikoht=koosseis.ametikoht; Thank you. In my case koosseis.ametikoht column does not contain null values. Si I fixed this in WHERE clause WHERE (iandmed.ametikoht is not null or koosseis.ametikoht is not null) I hope this produces same result in my case. Andrus.