tags:

views:

41

answers:

4

I have these tables:

customer:
    customer_id vat_number
    =========== ==========
              1 ES-0000001
              2 ES-0000002
              3 ES-0000003


invoice:
    invoice_id customer_id vat_number
    ========== =========== ==========
           100           1 NULL
           101           3 NULL
           102           3 NULL
           103           2 NULL
           104           3 NULL
           105           1 NULL

I want to fill the NULL values at invoice.vat_number with the current values from customer.vat_number. Is it possible to do it with a single SQL statement?

What I have so far triggers a syntax error:

UPDATE invoice
SET vat_number=cu.vat_number /* Syntax error around here */
FROM invoice iv
INNER JOIN customer cu ON iv.customer_id=cu.customer_id
WHERE invoice.invoice_id=iv.invoice_id;
+2  A: 
UPDATE invoice i, customer cu SET i.vat_number=cu.vat_number 
WHERE i.customer_id = cu.customer_id;

Here you go


SET vat_number=cu.vat_number /* Syntax error around here */ The error is because the var_number column name is ambiguous - MySQL does not know if this is i.vat_number or cu,vat_number.

Yasen Zhelev
@Yasen, I formatted the code in your answer.
RC
Thanks @RC I do not think that he really need a subquery for such a simple task.
Yasen Zhelev
This works fine but I find implicit joins hard to understand. Can this be rewritten as an INNER JOIN?
Álvaro G. Vicario
Then read what @OMG Ponies have written, but this is the smpliest and I would say best approach.
Yasen Zhelev
My syntax error is because the SET clause should be *after* the join specification. I've just realized that had started coding from a SQL-Server snippet that I had mistakenly taken as MySQL :_(
Álvaro G. Vicario
+2  A: 

Something like :

UPDATE invoice in
SET vat_number=(SELECT cu.vat_number FROM customer cu 
WHERE in.customer_id=cu.customer_id)
-- not tested
RC
This syntax works fine (except that `in` is a reserved keyword). Thank you!
Álvaro G. Vicario
This assumes that all `INVOICE.vat_number` values are NULL -- those that aren't, will still be overwritten with the `CUSTOMER.vat_number` value.
OMG Ponies
+4  A: 

Using MySQL, ANSI-92 JOIN syntax:

UPDATE INVOICE
  JOIN CUSTOMER ON CUSTOMER.customer_id = INVOICE.customer_id
   SET vat_number = CUSTOMER.vat_number  
 WHERE INVOICE.vat_number IS NULL

Using MySQL, ANSI-89 JOIN syntax:

UPDATE INVOICE, CUSTOMER 
   SET INVOICE.vat_number = CUSTOMER.vat_number  
 WHERE CUSTOMER.customer_id = INVOICE.customer_id
   AND INVOICE.vat_number IS NULL

For more info, see the MySQL UPDATE documentation. This is MySQL specific UPDATE statement syntax, not likely to be supported on other databases.

OMG Ponies
That's it: UPDATE + JOIN + SET. It's hard to spot from the manual although, now I know how it's done, it's kind of obvious... Thank you very much.
Álvaro G. Vicario
"ANSI-92 JOIN syntax" is misleading. The syntax posted is not compliant with ANSI-92: doesn't allow a JOIN at all, requires use of scalar subqueries e.g. `UPDATE INVOICE SET vat_number = (SELECT customer_id FROM CUSTOMER WHERE CUSTOMER.customer_id = INVOICE.customer_id) WHERE EXISTS (SELECT * FROM CUSTOMER WHERE CUSTOMER.customer_id = INVOICE.customer_id);`
onedaywhen
...noting that you later point out that it is proprietary syntax.
onedaywhen
A: 

UPDATE iv SET iv.vat_number=cu.vat_number FROM invoice iv INNER JOIN customer cu ON iv.customer_id=cu.customer_id

franklins