49

I'm trying to update a table called incode_warrants and set the warn_docket_no to the viol_docket_no from the incode_violations table.

When the SQL query below fires in PostgreSQL 9.3 I get:

Error : ERROR:  relation "iw" does not exist
LINE 1: update iw

How do I get this query right?

UPDATE iw
SET iw.warn_docket_no = iv.viol_docket_no
FROM incode_warrants as iw
INNER JOIN incode_warrantvs as iwvs
ON iw.warn_rid = iwvs.warnv_rid
INNER JOIN incode_violations as iv
ON iv.viol_citation_no = iwvs.warnv_citation_no
AND iv.viol_viol_no = iwvs.warnv_viol_no
1
  • Please ask 1 specific researched non-duplicate question. Either ask re 1 bad query/function with obligatory minimal reproducible example, including why you think it should return something else or are unsure at the 1st subexpression where you don't get what you expect or are stuck, justified by reference to authoritative documentation, or ask about your overall goal giving working parts you can do with justification & a minimal reproducible example--then misunderstood code doesn't belong. But please ask about unexpected behaviour 1st because misconceptions get in the way of your goal. How to Ask Help center Basic questions are faqs. Commented Apr 4 at 7:02

5 Answers 5

98

The same as valid UPDATE statement in Postgres:

UPDATE incode_warrants iw
SET    warn_docket_no = iv.viol_docket_no
FROM   incode_warrantvs  iwvs
JOIN   incode_violations iv ON iv.viol_citation_no = iwvs.warnv_citation_no
                           AND iv.viol_viol_no = iwvs.warnv_viol_no
WHERE  iw.warn_rid = iwvs.warnv_rid
-- AND iw.warn_docket_no IS DISTINCT FROM iv.viol_docket_no -- see below
;

You cannot just use a table alias in the FROM clause as target table in the UPDATE clause. The (one!) table to be updated comes right after UPDATE keyword (if we ignore a possible ONLY keyword in between). You can add an alias there if you want. That's the immediate cause of your error message, but there's more.

The column to be updated is always from the one table to be updated and cannot be table-qualified.

You don't need to repeat the target table in the FROM clause - except for special cases like this:

This optional addition can avoid pointless cost by suppressing updates that do not change anything:

AND iw.warn_docket_no IS DISTINCT FROM iv.viol_docket_no

See:

More in the excellent manual on UPDATE.

Sign up to request clarification or add additional context in comments.

4 Comments

Excellent answer, thanks for your help and expertise. I'm definitely going to read the manual and improve my technique!
I did have a question if you don't mind. I'm trying to get this update statement to fire off in a MASSIVE 400 LOC stored proc. I've injected it into the SP and I set a Raise info to note when it fires, but in running the stored proc it never fires. Running the update by itself works fine. Should I create a new question to address this?
@shakycode: Yes, a new question with all the necessary details is the right move. Comments are not the place. You can always link to this one for context.
Will do! I need to somehow anonymize the stored proc since it has proprietary schema data in it. I'll be posting soon. Thanks again for your help, Erwin!
7

Your query should look like this:

UPDATE incode_warrants
SET warn_docket_no = incode_violations.viol_docket_no
FROM incode_violations
WHERE incode_violations.viol_citation_no = incode_warrants.warnv_citation_no
AND incode_violations.viol_viol_no = incode_warrants.warnv_viol_no;

You don't need any other join. With this query you just update a column in one table with values from a column from another table. Of course, it updates only when WHERE condition is true.

4 Comments

Thanks for the quick answer. When I run it I get this: Error : ERROR: column incode_warrants.warnv_citation_no does not exist LINE 4: WHERE incode_violations.viol_citation_no = incode_warrants.w...
Could you update your question with a schema? I don't knock how your tables look like. Need more explanation.
You may have overlooked that incode_warrants and incode_warrantvs are two different tables - unless that's a typo in the question, of course.
As Erwin mentioned, this solution is missing incode_warrantvs which is why I down voted.
7
UPDATE incode_warrants iw
     SET warn_docket_no = iv.viol_docket_no
FROM incode_warrantvs AS iwvs, incode_violations AS iv 
WHERE iv.viol_citation_no = iwvs.warnv_citation_no AND
      iv.viol_viol_no = iwvs.warnv_viol_no AND
      iw.warn_rid = iwvs.warnv_rid;

Comments

3

Your update a table, not the join

update incode_warrants ALIAS
set warn_docket_no = iv.viol_docket_no
from incode_warrantvs as iw 
...

2 Comments

You cannot table-qualify target columns of an UPDATE statement in Postgres.
@ErwinBrandstetter Thanks for your comment. I fix it. But my answer just address one problem and after seeing your answer realize wasnt a complete answer.
2

That is my code, i generate my join and enclosure in a and after join with my updateable table and in my where i compare my identitys, sorry for my english

update cs_ticket ct
set site_name = a.name
from (
    select ct.id, cs."name" 
    from cs_ticket ct 
    inner join cs_net_segment cns 
    on ct.affected_ip like cns.ip || '.%'
    and end_date is null
    inner join cs_site cs 
    on cs.id = cns.site_id)a
where ct.id = a.id;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.