Bug #24302 | INSERT ...SELECT...ON DUPLICATE KEY not recognizing source field(s) | ||
---|---|---|---|
Submitted: | 14 Nov 2006 15:33 | Modified: | 15 Nov 2006 10:48 |
Reporter: | Darren Arrowsmith | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server | Severity: | S2 (Serious) |
Version: | 4.1.21 | OS: | Windows (Windows) |
Assigned to: | CPU Architecture: | Any |
[14 Nov 2006 15:33]
Darren Arrowsmith
[14 Nov 2006 16:42]
Giuseppe Maxia
This is expected behavior. You are trying to use an alias instead of a column name. To do what you expect, you can either repeat the expression you used before, or save it to a user variable. Do either INSERT INTO t1 (UID_Product, Quantity) SELECT UID_Product, IF(ActualPrice<0,-1,+1) AS Qty FROM t2 ON DUPLICATE KEY UPDATE Quantity=Quantity+IF(ActualPrice<0,-1,+1); or INSERT INTO t1 (UID_Product, Quantity) SELECT UID_Product, @qty := IF(ActualPrice<0,-1,+1) FROM t2 ON DUPLICATE KEY UPDATE Quantity=Quantity + @qty; Regards Giuseppe
[14 Nov 2006 17:04]
Giuseppe Maxia
As shown in my previous comment, this behavior is expected, and therefore this is not a bug. See the manual: http://dev.mysql.com/doc/refman/5.0/en/problems-with-alias.html
[14 Nov 2006 17:46]
Darren Arrowsmith
Your first suggestion: INSERT INTO t1 (UID_Product, Quantity) SELECT UID_Product, IF(ActualPrice<0,-1,+1) AS Qty FROM t2 ON DUPLICATE KEY UPDATE Quantity=Quantity+IF(ActualPrice<0,-1,+1); does not work. It gives: [1054] Unknown column 'ActualPrice' in 'field list' and your second suggestion: INSERT INTO t1 (UID_Product, Quantity) SELECT UID_Product, @qty := IF(ActualPrice<0,-1,+1) FROM t2 ON DUPLICATE KEY UPDATE Quantity=Quantity + @qty does not work either, it gives: [1110] Column 'Quantity' specified twice
[14 Nov 2006 19:35]
Giuseppe Maxia
Using your table description and contents, the queries from my previous comment are working fine on both Linux and Windows. See for yourself: mysql> select version(); +------------+ | version() | +------------+ | 4.1.21-max | +------------+ 1 row in set (0.00 sec) mysql> CREATE TABLE t1 ( -> UID_Product int(10) unsigned default '0', -> Quantity int(10) NOT NULL default '0', -> PRIMARY KEY (UID_Product) -> ) ENGINE=MyISAM DEFAULT CHARSET=latin1; Query OK, 0 rows affected (0.05 sec) mysql> mysql> CREATE TABLE t2 ( -> UID_Product int(10) unsigned default '0', -> ActualPrice decimal(10,2) NOT NULL default '0.00', -> PRIMARY KEY (UID_Product) -> ) ENGINE=MyISAM DEFAULT CHARSET=latin1; Query OK, 0 rows affected (0.07 sec) mysql> mysql> INSERT INTO t2 VALUES (1,1.99); Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO t2 VALUES (2,-0.50); Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO t1 (UID_Product, Quantity) -> SELECT UID_Product, IF(ActualPrice<0,-1,+1) AS Qty -> FROM t2 -> ON DUPLICATE KEY -> UPDATE Quantity=Quantity+IF(ActualPrice<0,-1,+1); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> INSERT INTO t1 (UID_Product, Quantity) -> SELECT UID_Product, @qty := IF(ActualPrice<0,-1,+1) -> FROM t2 -> ON DUPLICATE KEY -> UPDATE Quantity=Quantity + @qty; Query OK, 4 rows affected (0.00 sec) Records: 2 Duplicates: 2 Warnings: 0 You can cut-and-paste the following script into a mysql command line client and report its output: drop table if exists t1,t2; select version(); CREATE TABLE t1 ( UID_Product int(10) unsigned default '0', Quantity int(10) NOT NULL default '0', PRIMARY KEY (UID_Product) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; CREATE TABLE t2 ( UID_Product int(10) unsigned default '0', ActualPrice decimal(10,2) NOT NULL default '0.00', PRIMARY KEY (UID_Product) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; INSERT INTO t2 VALUES (1,1.99); INSERT INTO t2 VALUES (2,-0.50); select 't1' as t; select * from t1; select 't2' as t; select * from t2; INSERT INTO t1 (UID_Product, Quantity) SELECT UID_Product, IF(ActualPrice<0,-1,+1) AS Qty FROM t2 ON DUPLICATE KEY UPDATE Quantity=Quantity+IF(ActualPrice<0,-1,+1); select 't1' as t; select * from t1; select 't2' as t; select * from t2; INSERT INTO t1 (UID_Product, Quantity) SELECT UID_Product, @qty := IF(ActualPrice<0,-1,+1) FROM t2 ON DUPLICATE KEY UPDATE Quantity=Quantity + @qty; select 't1' as t; select * from t1; select 't2' as t; select * from t2;
[15 Nov 2006 10:48]
Darren Arrowsmith
I must apologise profusely. Our customer is running 4.1.21 - our development server is running 4.1.12 (I didn't notice the version difference as the numbers were so similar). I have upgraded our server to 4.1.21 and concur that both your queries work - I must assume the problem has been fixed somewhere between 4.1.12 -> 4.1.21. Thanks all for your help. Darren