Thread: getting rid of "Adding missing FROM-clause entry...."

getting rid of "Adding missing FROM-clause entry...."

From
Rajesh Kumar Mallah
Date:
Hi I am having problem with an UPDATE ... FROM
SQL where the FROM table is a subquery.

UPDATE  profile_master set title1=a.title1  FROM 
(

SELECT company_id , titile as title1 ,fname as fname1 ,mname as mname1 ,lname as 
lname1 ,company_position as desg1  from public.catalog_key_contacts  where  
company_id=profile_master.company_id order by contact_id limit 1 offset 0
)  as a 
where profile_master.source='CATALOG' ;
NOTICE:  Adding missing FROM-clause entry in subquery for table "profile_master"
UPDATE 711

its showing an update of 711 however all the 711 matching rows are getting 
updated to the same value.

can anyone tell me how to write this query properly ?

Regds
Mallah.






-- 
Rajesh Kumar Mallah,
Project Manager (Development)
Infocom Network Limited, New Delhi
phone: +91(11)6152172 (221) (L) ,9811255597 (M)

Visit http://www.trade-india.com ,
India's Leading B2B eMarketplace.



Re: getting rid of "Adding missing FROM-clause entry...."

From
Rajesh Kumar Mallah
Date:


Actually i have to update multiple columns my original 
query was:

UPDATE  profile_master    SET
title1=a.title1 , fname1=a.fname1 , mname1=a.mname1 ,lname1=a.lname1 , desg1 = a.desg1 FROM 

(  SELECT company_id , titile as title1 ,fname as fname1 ,mname as mname1 ,  lname as lname1 ,company_position as desg1
from public.catalog_key_contacts as b   where  b.company_id=profile_master.company_id order by contact_id limit 1
offset0)  
 

as a WHERE 

profile_master.source='CATALOG' ;

Regds
Mallah.



On Thursday 17 Apr 2003 3:57 pm, Rajesh Kumar Mallah wrote:
> Hi I am having problem with an UPDATE ... FROM
> SQL where the FROM table is a subquery.
>
> UPDATE  profile_master set title1=a.title1  FROM
> (
>
> SELECT company_id , titile as title1 ,fname as fname1 ,mname as mname1
> ,lname as lname1 ,company_position as desg1  from
> public.catalog_key_contacts  where company_id=profile_master.company_id
> order by contact_id limit 1 offset 0 )  as a
> where profile_master.source='CATALOG' ;
> NOTICE:  Adding missing FROM-clause entry in subquery for table
> "profile_master" UPDATE 711
>
> its showing an update of 711 however all the 711 matching rows are getting
> updated to the same value.
>
> can anyone tell me how to write this query properly ?
>
> Regds
> Mallah.

-- 
Rajesh Kumar Mallah,
Project Manager (Development)
Infocom Network Limited, New Delhi
phone: +91(11)6152172 (221) (L) ,9811255597 (M)

Visit http://www.trade-india.com ,
India's Leading B2B eMarketplace.



Re: getting rid of "Adding missing FROM-clause entry...."

From
Christoph Haller
Date:
>
> Actually i have to update multiple columns my original
> query was:
>
> UPDATE  profile_master    SET
>
>  title1=a.title1 , fname1=a.fname1 , mname1=a.mname1 ,
>  lname1=a.lname1 , desg1 = a.desg1 FROM
>
> (
>    SELECT company_id , titile as title1 ,fname as fname1 ,mname as
mname1 ,
>    lname as lname1 ,company_position as desg1  from
public.catalog_key_contacts as b
>    where  b.company_id=profile_master.company_id order by contact_id
limit 1 offset 0)
>
> as a WHERE
>
> profile_master.source='CATALOG' ;
>
> > Hi I am having problem with an UPDATE ... FROM
> > SQL where the FROM table is a subquery.
> >
> > UPDATE  profile_master set title1=a.title1  FROM
> > (
> >
> > SELECT company_id , titile as title1 ,fname as fname1 ,mname as
mname1
> > ,lname as lname1 ,company_position as desg1  from
> > public.catalog_key_contacts  where
company_id=profile_master.company_id
> > order by contact_id limit 1 offset 0 )  as a
> > where profile_master.source='CATALOG' ;
> > NOTICE:  Adding missing FROM-clause entry in subquery for table
> > "profile_master" UPDATE 711
> >
> > its showing an update of 711 however all the 711 matching rows are
getting
> > updated to the same value.
> >
> > can anyone tell me how to write this query properly ?
> >
I think you need a second reference to the profile_master table.
And why are you using "limit 1 offset 0"?
So I'd say

UPDATE  profile_master    SET
title1=a.title1 , fname1=a.fname1 , mname1=a.mname1 ,lname1=a.lname1 , desg1 = a.desg1 FROM

(  SELECT company_id , title as title1 ,fname as fname1 ,mname as mname1
,  lname as lname1 ,company_position as desg1  from public.catalog_key_contacts as b ,profile_master as c  where
b.company_id=c.company_idorder by contact_id )
 

as a WHERE

source='CATALOG' ;

Does this work?
Regards, Christoph



Re: getting rid of "Adding missing FROM-clause entry...."

From
Rajesh Kumar Mallah
Date:
On Thursday 17 Apr 2003 6:50 pm, Christoph Haller wrote:
> > Actually i have to update multiple columns my original
> > query was:
> >
> > UPDATE  profile_master    SET
> >
> >  title1=a.title1 , fname1=a.fname1 , mname1=a.mname1 ,
> >  lname1=a.lname1 , desg1 = a.desg1 FROM
> >
> > (
> >    SELECT company_id , titile as title1 ,fname as fname1 ,mname as
>
> mname1 ,
>
> >    lname as lname1 ,company_position as desg1  from
>
> public.catalog_key_contacts as b
>
> >    where  b.company_id=profile_master.company_id order by contact_id
>
> limit 1 offset 0)
>
> > as a WHERE
> >
> > profile_master.source='CATALOG' ;
> >
> > > Hi I am having problem with an UPDATE ... FROM
> > > SQL where the FROM table is a subquery.
> > >
> > > UPDATE  profile_master set title1=a.title1  FROM
> > > (
> > >
> > > SELECT company_id , titile as title1 ,fname as fname1 ,mname as
>
> mname1
>
> > > ,lname as lname1 ,company_position as desg1  from
> > > public.catalog_key_contacts  where
>
> company_id=profile_master.company_id
>
> > > order by contact_id limit 1 offset 0 )  as a
> > > where profile_master.source='CATALOG' ;
> > > NOTICE:  Adding missing FROM-clause entry in subquery for table
> > > "profile_master" UPDATE 711
> > >
> > > its showing an update of 711 however all the 711 matching rows are
>
> getting
>
> > > updated to the same value.
> > >
> > > can anyone tell me how to write this query properly ?
>
> I think you need a second reference to the profile_master table.
> And why are you using "limit 1 offset 0"?

becuase the subquery results in mutiple rowss.
I want the first row to update title1,fname1,mname1,lname1,degs1

and use the second row by using "limit 1 offset 1" to
update title2,fname2,mname2,lname2,degs2 etc

do u still want me to try the query u gave?
(actually i did try and its giving some trivial error)

regds
mallah.


> So I'd say
>
> UPDATE  profile_master    SET
>
>  title1=a.title1 , fname1=a.fname1 , mname1=a.mname1 ,
>  lname1=a.lname1 , desg1 = a.desg1 FROM
>
> (
>    SELECT company_id , title as title1 ,fname as fname1 ,mname as mname1
> ,
>    lname as lname1 ,company_position as desg1
>    from public.catalog_key_contacts as b ,profile_master as c
>    where  b.company_id=c.company_id order by contact_id )
>
> as a WHERE
>
> source='CATALOG' ;
>
> Does this work?
> Regards, Christoph
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: if posting/reading through Usenet, please send an appropriate
> subscribe-nomail command to majordomo@postgresql.org so that your
> message can get through to the mailing list cleanly

-- 
Rajesh Kumar Mallah,
Project Manager (Development)
Infocom Network Limited, New Delhi
phone: +91(11)6152172 (221) (L) ,9811255597 (M)

Visit http://www.trade-india.com ,
India's Leading B2B eMarketplace.



Re: getting rid of "Adding missing FROM-clause entry...."

From
Christoph Haller
Date:
> > And why are you using "limit 1 offset 0"?
>
> becuase the subquery results in mutiple rowss.
> I want the first row to update title1,fname1,mname1,lname1,degs1
>
> and use the second row by using "limit 1 offset 1" to
> update title2,fname2,mname2,lname2,degs2 etc
>
> do u still want me to try the query u gave?
> (actually i did try and its giving some trivial error)
>
No. Looks like  a misunderstanding.
Do I get it right this time assuming you want to
set up multiple update commands which update
only one row at a time?
Regards, Christoph



Re: getting rid of "Adding missing FROM-clause entry...."

From
Rajesh Kumar Mallah
Date:
On Thursday 17 Apr 2003 7:39 pm, Christoph Haller wrote:
> > > And why are you using "limit 1 offset 0"?
> >
> > becuase the subquery results in mutiple rowss.
> > I want the first row to update title1,fname1,mname1,lname1,degs1
> >
> > and use the second row by using "limit 1 offset 1" to
> > update title2,fname2,mname2,lname2,degs2 etc
> >
> > do u still want me to try the query u gave?
> > (actually i did try and its giving some trivial error)
>
> No. Looks like  a misunderstanding.
> Do I get it right this time assuming you want to
> set up multiple update commands which update
> only one row at a time?
> Regards, Christoph


Dear Chris ,

Thanks so much for ur interest.
I have prepared a prototype for this
problem and including the SQL.

actually my orignal problem is to update
10 *columns* in profile master first five comes 
from first entry in another table and remaining
5 columns comes from the second corresponding
row in the other table. the two rows in the
second columns have the same company_id but
different contact_id. sort of denormalizing
excercise.

this needs to be done for all the companies
in 2 seperate update commands(or better 1).


Eg: below is a prototype for the problem.
(SQL are included below)

Table t_b
+----+--------+-------+-------+
| id | con_id | fname | mname |
+----+--------+-------+-------+
|  1 |      1 | X     | Y     |
|  1 |      2 | U     | V     |
|  2 |      1 | S     | T     |
+----+--------+-------+-------+

shud be translated to

+----+--------+--------+--------+--------+
| id | fname1 | mname1 | fname2 | mname2 |
+----+--------+--------+--------+--------+
|  1 | X      | Y      | U      | V      |
|  2 | S      | T      | NULL   | NULL   |
+----+--------+--------+--------+--------+

but
UPDATE t_a set fname1=foo.fname1 , mname1=foo.mname1  FROM 
(select fname as fname1 , mname as mname1 from t_b where id=t_a.idorder by con_id limit 1 offset 0) as foo ;

gives:
NOTICE:  Adding missing FROM-clause entry in subquery for table "t_a"
and updates wrongly.

tradein_clients=# SELECT * from t_a;
+----+--------+--------+--------+--------+
| id | fname1 | mname1 | fname2 | mname2 |
+----+--------+--------+--------+--------+
|  1 | X      | Y      | NULL   | NULL   |
|  2 | X      | Y      | NULL   | NULL   |
+----+--------+--------+--------+--------+
(2 rows)

// SQL BEGINS.
CREATE TABLE t_b (   id integer,   con_id integer,   fname character varying,   mname character varying
);
INSERT INTO t_b (id, con_id, fname, mname) VALUES (1, 1, 'X', 'Y');
INSERT INTO t_b (id, con_id, fname, mname) VALUES (1, 2, 'U', 'V');
INSERT INTO t_b (id, con_id, fname, mname) VALUES (2, 1, 'S', 'T');

CREATE TABLE t_a (   id integer,   fname1 character varying,   mname1 character varying,   fname2 character varying,
mname2character varying
 
);
INSERT INTO t_a (id, fname1, mname1, fname2, mname2) VALUES (1, 'X', 'Y', NULL, NULL);
INSERT INTO t_a (id, fname1, mname1, fname2, mname2) VALUES (2, 'X', 'Y', NULL, NULL);
// SQL ENDS.






>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: if posting/reading through Usenet, please send an appropriate
> subscribe-nomail command to majordomo@postgresql.org so that your
> message can get through to the mailing list cleanly

-- 
Rajesh Kumar Mallah,
Project Manager (Development)
Infocom Network Limited, New Delhi
phone: +91(11)6152172 (221) (L) ,9811255597 (M)

Visit http://www.trade-india.com ,
India's Leading B2B eMarketplace.



Re: getting rid of "Adding missing FROM-clause entry...."

From
Manfred Koizar
Date:
On Thu, 17 Apr 2003 20:21:28 +0530, Rajesh Kumar Mallah
<mallah@trade-india.com> wrote:
>actually my orignal problem is to update
>10 *columns* in profile master first five comes 
>from first entry in another table

This part is easy (using table and column names from your prototype):

UPDATE t_a  SET fname1=foo.fname , mname1=foo.mname FROM (SELECT DISTINCT ON (id) id, fname, mname         FROM t_b
  ORDER BY id, con_id        ) AS fooWHERE t_a.id = foo.id;
 

> and remaining
>5 columns comes from the second corresponding
>row in the other table.

This is a bit harder, because while DISTINCT ON (id) can be viewed as
sort of LIMIT 1 OFFSET 0 for each group of equal ids, there is no such
construct to select the *second* row of each group.  So we build a
subquery that does not contain the first row of each group and take
the first row of the rest, i.e. the second row of the original group:

UPDATE t_a  SET fname2=foo.fname , mname2=foo.mname FROM (SELECT DISTINCT ON (b2.id) b2.id, b2.fname, b2.mname
FROMt_b AS b1, t_b AS b2      WHERE b1.id = b2.id AND b1.con_id < b2.con_id      ORDER BY b2.id, b2.con_id) AS fooWHERE
t_a.id= foo.id;
 

Note that this does not set xname2 to NULL where no second
corresponding row exists.  You might need a third UPDATE statement to
do this.

ServusManfred



Re: getting rid of "Adding missing FROM-clause entry...."

From
Rajesh Kumar Mallah
Date:
Thanks Manfred,

i think two of your queries will work for me.
but i need to take a closer look.

BTW any idea why the query which i posted is not
working? and issuing a NOTICE.

regds
mallah.

On Thursday 17 Apr 2003 9:00 pm, Manfred Koizar wrote:
> On Thu, 17 Apr 2003 20:21:28 +0530, Rajesh Kumar Mallah
>
> <mallah@trade-india.com> wrote:
> >actually my orignal problem is to update
> >10 *columns* in profile master first five comes
> >from first entry in another table
>
> This part is easy (using table and column names from your prototype):
>
> UPDATE t_a
>    SET fname1=foo.fname , mname1=foo.mname
>   FROM (SELECT DISTINCT ON (id) id, fname, mname
>           FROM t_b
>          ORDER BY id, con_id
>          ) AS foo
>  WHERE t_a.id = foo.id;
>
> > and remaining
> >5 columns comes from the second corresponding
> >row in the other table.
>
> This is a bit harder, because while DISTINCT ON (id) can be viewed as
> sort of LIMIT 1 OFFSET 0 for each group of equal ids, there is no such
> construct to select the *second* row of each group.  So we build a
> subquery that does not contain the first row of each group and take
> the first row of the rest, i.e. the second row of the original group:
>
> UPDATE t_a
>    SET fname2=foo.fname , mname2=foo.mname
>   FROM (SELECT DISTINCT ON (b2.id) b2.id, b2.fname, b2.mname
>         FROM t_b AS b1, t_b AS b2
>        WHERE b1.id = b2.id AND b1.con_id < b2.con_id
>        ORDER BY b2.id, b2.con_id) AS foo
>  WHERE t_a.id = foo.id;
>
> Note that this does not set xname2 to NULL where no second
> corresponding row exists.  You might need a third UPDATE statement to
> do this.
>
> Servus
>  Manfred

-- 
Rajesh Kumar Mallah,
Project Manager (Development)
Infocom Network Limited, New Delhi
phone: +91(11)6152172 (221) (L) ,9811255597 (M)

Visit http://www.trade-india.com ,
India's Leading B2B eMarketplace.



Re: getting rid of "Adding missing FROM-clause entry...."

From
Manfred Koizar
Date:
On Thu, 17 Apr 2003 21:22:17 +0530, Rajesh Kumar Mallah
<mallah@trade-india.com> wrote:
>BTW any idea why the query which i posted is not
>working? and issuing a NOTICE.

I guess, in 
UPDATE t1   SET ...  FROM (SELECT ... FROM t2        WHERE t2.id = t1.id);

the subselect is not correlated because t1 and the subquery are on the
same level.  So the subquery is treated like a standalone query and as
it does not have t1 in its FROM clause, t1 is added automatically.
Then the result of the subquery is joined to each row of t1 for the
update.  This also explains why all rows were updated to the same
values.

ServusManfred



Re: getting rid of "Adding missing FROM-clause entry...."

From
Manfred Koizar
Date:
On Thu, 17 Apr 2003 21:22:17 +0530, Rajesh Kumar Mallah
<mallah@trade-india.com> wrote:
>i think two of your queries will work for me.

I hope so, but ...

>I wrote:
>> UPDATE t_a
>>    SET fname2=foo.fname , mname2=foo.mname
>>   FROM (SELECT DISTINCT ON (b2.id) b2.id, b2.fname, b2.mname
>>         FROM t_b AS b1, t_b AS b2
>>        WHERE b1.id = b2.id AND b1.con_id < b2.con_id
>>        ORDER BY b2.id, b2.con_id) AS foo
>>  WHERE t_a.id = foo.id;

... this can be slow, if you have large groups of equal id, because
each group blows up to n^2/2 rows.  You might be better off with a
subselect like
SELECT DISTINCT ON (b2.id) b2.id, b2.fname, b2.mname  FROM t_b AS b2 WHERE EXISTS (SELECT *               FROM t_b AS
b1              WHERE b1.id = b2.id AND b1.con_id < b2.con_id) ORDER BY b2.id, b2.con_id
 

or
SELECT b2.id, b2.fname, b2.mname  FROM t_b AS b2 WHERE (SELECT count(*)          FROM t_b AS b1         WHERE b1.id =
b2.idAND b1.con_id < b2.con_id) = 1
 

The latter having the advantage of being standard SQL.  You have to
experiment a little to find out what works best for you.

BTW, my proposed UPDATE statements don't handle this case very well:
id | con_id | fname | mname
----+--------+-------+------- 1 |      1 | first | ... 1 |      1 | 2nd   | ... 1 |      2 | 3rd   | ... 1 |      2 |
4th  | ...
 

ServusManfred