Strange Sql Update behavior - mysql

I'm trying to update supplier table on both PostgreSQL and MySQL using the following update statement:
UPDATE SUPPLIERS SET CURDEBT = CURDEBT + 10 WHERE ID = 5
This works fine as long as the CURDEBT column not equals null, if it is null it won't update the record. Does any body have a solution to this problem?
Thanks

In SQL, NULL is not the same thing as 0. Any operations on a NULL value still yield a NULL result. NULL + 10 is still NULL.
If you want NULL to automatically turn into "0" in this query, try this (PostgreSQL):
UPDATE SUPPLIERS SET CURDEBT = coalesce(CURDEBT, 0) + 10 WHERE ID = 5
Or MySQL:
UPDATE SUPPLIERS SET CURDEBT = ifnull(CURDEBT, 0) + 10 WHERE ID = 5

Use coalesce
UPDATE SUPPLIERS SET CURDEBT = coalesce(CURDEBT,0) + 10 WHERE ID = 5
See sqlbook

What you're looking for is COALESCE:
UPDATE SUPPLIERS
SET CURDEBT = COALESCE(CURDEBT, 0) + 10
WHERE ID = 5
Coalesce (MySQL):
http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_coalesce

That behaviour is exactly what you should expect from SQL, since null + x = null, always.
You can solve it by using the COALESCE function, available in both postgres and mysql, like so:
UPDATE SUPPLIERS SET CURDEBT = COALESCE(CURDEBT,0) + 10 WHERE ID = 5

Related

updating record based on set if condition in gorm

I am trying to update the records in my Go project when trying to do so there is some need to update based on the conditions. I have figured out a way in mysql but that query need to be converted into gorm. Heere is the mysql query:
update table_name SET field_name1 = IF (field_name2 = 2, 1 , 0) where field_name3 = 6;
I have done this using
query := fmt.Sprintf(`UPDATE table_name SET field_name1 = IF (field_name2 = "%s", 1 , 0) where field_name3 = "%s"`, field_value1, field_value2)
s.DB.Exec(query)

mysql update with if and max

I have lost hours on this and nothing works for me.
I have filed strp_aa that is default NULL. The filed strp_aa should update only if its null with MAX strp_aa + 1, and if its not null if it already has a number it should stay the same.
short version of code is
UPDATE STRANKEP
SET strp_aa = IF(strp_aa=null, strp_aa+1, strp_aa)
WHERE strp_ID=36;
Also tired
UPDATE STRANKEP
SET strp_aa = IF(strp_aa=null, (SELECT MAX(strp_aa)) +1, (SELECT (strp_aa) WHERE strp_ID=36)
WHERE strp_ID=36;
I tried multiple things like this one mentioned here Update MySQL with if condition:
UPDATE STRANKEP
SET strp_aa = CASE WHEN strp_aa = NULL THEN MAX(strp_aa) + 1 ELSE strp_aa END
WHERE strp_ID = 36;
I have also found this mysql query to update field to max(field) + 1 and tried all sorts of combinations with supplied answer and it wont work for me. One of the version is:
UPDATE STRANKEP
SET strp_aa = IF((SELECT strp_aa )!=null,((SELECT selected_value2 FROM (SELECT (strp_aa) AS selected_value2 FROM STRANKEP WHERE strp_ID=36) AS sub_selected_value2)), ((SELECT selected_value FROM (SELECT MAX(strp_aa) AS selected_value FROM STRANKEP) AS sub_selected_value) + 1) )
WHERE strp_ID=36;
This just keep adding one even if there is a number set on strp_aa...
I don't know what else to try.
EDIT:
Had s little problem with #GMB answer because all fields are starting with NULL, so max(strp_aa) gives 0 results in case none of the fields had a number in it.
I solved that with COALESCE statement and posting it here if someone has similar problem.
UPDATE STRANKEP t
CROSS JOIN (select COALESCE(MAX(strp_aa),0) max_strp_aa from STRANKEP) m
set t.strp_aa = m.max_strp_aa + 1
where t.strp_ID = 36 and t.strp_aa is null
You can use the update ... join syntax for this:
update strankep s
cross join (select max(strp_aa) max_strp_aa from strankep) m
set s.strp_aa = m.max_strp_aa + 1
where s.strp_id = 36 and s.strp_aa is null
The cross join brings the max value of strp_aa over the whole table. The where clause eliminate row(s) where strp_aa is not null.

Check field value, do a calculation (division) and update column values

I need to make some calculation in MySQL table which contains hundreds of rows.
I've got a field called "VAT-Code" which contain a code : 1 or 2
I've got a field called "Price" which contain the price
Query should do the following :
If "VAT-Code" value = 1 calculate "Price" / 1,08 -> update the field value
If "VAT-Code" value = 2 calculate "Price" / 1,025 -> update the field value
Ok I have tried this :
I have tried this :
UPDATE jos_tempcsv SET selling price = CASE `VAT-Code` WHEN = 1 THEN `selling price`/1.08 WHEN = 2 THEN `selling price`/1.025 ELSE NULL END
selling price is the field with the price
But I get the following error :
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'price = CASE VAT-Code WHEN = 1 THEN selling price/1.08 WHEN = 2 THEN `sellin' at line 1
You can run UPDATE with CASE:
UPDATE yourtable SET yourfield=CASE `VAT-Code` WHEN 1 THEN `Price`/1.08 WHEN 2 THEN `Price`/1.025 ELSE NULL END;
Or you can run this as two separate UPDATEs:
UPDATE yourtable SET yourfield=`Price`/1.08 WHERE `VAT-Code`=1;
UPDATE yourtable SET yourfield=`Price`/1.025 WHERE `VAT-Code`=2;
You can try the below sql query :
UPDATE yourtable table1,(SELECT * FROM `yourtable` WHERE VAT-Code = 1) table2 SET table1.yourfield = (table2.price/1.08) WHERE table1.VAT-Code = 1
UPDATE yourtable table1,(SELECT * FROM `yourtable` WHERE VAT-Code = 2) table2 SET table1.yourfield = (table2.price/1.025) WHERE table1.VAT-Code = 1
This query works fine now :
UPDATE jos_tempcsv SET `selling price` = `selling price`/1.08 WHERE `VAT-Code`=1;
UPDATE jos_tempcsv SET `selling price` = `selling price`/1.025 WHERE `VAT-Code`=2;
Two queries in one
UPDATE jos_tempcsv SET `selling price` = CASE `VAT-Code` WHEN 1 THEN `selling price`/1.08 WHEN 2 THEN `selling price`/1.025 ELSE NULL END;

Update table with subquery works on mysql but error on oracle

I have table named TABLE_A looks like this :
ID DATA VALUE LM
---------------------------------
1 7 9 NULL
2 10 5 NULL
3 4 7 NULL
This is not actually my table, i use this to shorten my question.
Now I want to update table_a with subquery.
This is my query :
UPDATE TABLE_A,
(SELECT VALUE AS VAL FROM TABLE_A WHERE ID = 2) AS TEMP
SET TABLE_A.LM = TABLE_A.VALUE + TEMP.VAL
WHERE TABLE_A.ID = 1
This query works on Mysql but in oracle I got error :
[Err] ORA-00971: missing SET keyword
EDIT :
This is my table [SDM_ABSENSI] :
PERIODE TGL_IN TGL_OUT IN OUT LM TL
------------------------------------------------------------------
20141011 11/01/2014 11/01/2014 08:00 17:00 NULL NULL
20141012 12/01/2014 13/01/2014 22:00 07:30 NULL NULL
20141013 13/01/2014 13/01/2014 08:00 17:00 NULL NULL
My query :
UPDATE SDM_ABSENSI A
(
SELECT PERIODE, TGL_IN, TGL_OUT, IN, OUT,
TO_DATE(TO_CHAR(TGL_IN,'YYYY-MM-DD')||' '||IN,'YYYY-MM-DD hh24:mi') AS MASUK,
TO_DATE(TO_CHAR(TGL_OUT,'YYYY-MM-DD')||' '||OUT,'YYYY-MM-DD hh24:mi') AS KELUAR
FROM SDM_ABSENSI
WHERE SUBSTR(PERIODE,0,6) = '201410'
)ABSEN
SET A.LM = (24*60) * (ABSEN.KELUAR - ABSEN.MASUK),
A.TL = CASE WHEN (24*60) * (ABSEN.KELUAR - ABSEN.MASUK) < 0
THEN 0 ELSE (24*60) * (ABSEN.KELUAR - ABSEN.MASUK)
END
WHERE SUBSTR(A.PERIODE,0,6) = '201410'
AND A.PERIODE = ABSEN.PERIODE
And i got error :
[Err] ORA-00971: missing SET keyword
Please help,
Thanks in advance
Oracle does not support Update from Join Syntax. Instead you can use Merge. Try this.
MERGE
INTO SDM_ABSENSI
USING (
SELECT PERIODE, TGL_IN, TGL_OUT, IN, OUT,
TO_DATE(To_char(TGL_IN,'YYYY-MM-DD')||' '||IN,'YYYY-MM-DD hh24:mi') AS MASUK,
TO_DATE(TO_CHAR(TGL_OUT,'YYYY-MM-DD')||' '||OUT,'YYYY-MM-DD hh24:mi') AS KELUAR
FROM SDM_ABSENSI
WHERE SUBSTR(PERIODE,0,6) = '201410'
) ABSEN
ON SDM_ABSENSI.PERIODE = ABSEN.PERIODE
WHEN MATCHED THEN
UPDATE
SET SDM_ABSENSI.LM = ( 24 * 60 ) * ( ABSEN.KELUAR - ABSEN.MASUK ),
SDM_ABSENSI.TL = CASE
WHEN ( 24 * 60 ) * ( ABSEN.KELUAR - ABSEN.MASUK ) < 0 THEN 0
ELSE ( 24 * 60 ) * ( ABSEN.KELUAR - ABSEN.MASUK )
END
I don't think you can write such a subquery in Oracle. You should maybe checkout the update statement as its defined in the oracle documentation, here http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/update_statement.htm
Having said that, what do you really want to do here? What value and under which conditions do you want to assign to the column LM?
That query doesn't look so good, in my opinion. You're trying to build a temporary table from the data stored in table_a and update that same table_a with values from that temporal table... but how? With the maximum of the temporal table? With the value of the same register when the condition is met?
I don't see how that query could work in MySQL either to be honest.
To sum up, could you provide additional info?
[EDIT] Just saw the modification in the question. You can remove the subquery from where it is and place it in the where statement...
UPDATE TABLE_A
SET TABLE_A.LM = TABLE_A.VALUE + (SELECT VALUE AS VAL FROM TABLE_A WHERE ID = 2)
WHERE TABLE_A.ID = 1

Update Same mysql field twice in single query

I am not sure if its possible or not, Just want to know if it is. I have column plan_popular which has default value 0. Lets same i have a list :
Plan Name | plan_popular | amount
===================================
plan A 0 25.00
plan B 1 50.00
plan C 0 90.00
This is how i am doing:
$stmt = "update {CI}plans set plan_popular = 0";
$this->db->query($stmt);
$stmt2 = "update {CI}plans set plan_popular = 1 where plan_id = ?";
$this->db->query( $stmt2, array($plan_id) );
Now i have set the plan C to make. Now i want to reset it and want to make popular plan C to 1. What i am doing is running two queries, One i reset and make the plan_popular 0 and the second is get the update the plan C to 1 with there id. Is it possible in single query?
You can use an expression to determine the value to assign:
UPDATE {CI}plans
SET plan_popular = IF(plan_id = ?, 1, 0);
try this,
UPDATE {CI}plans
SET `plan_popular` = CASE `Plan Name`
WHEN 'plan C' THEN 1
ELSE 0
END
WHERE `Plan Name` IN((select `Plan Name` from {CI}plans where plan_popular=1 ) , 'plan C');
Updates can be expensive, what with manipulating locks, triggers and constraints firing, etc. In general, you want to avoid updating a field to the same value it already has. In English, if plan_id = variable and plan_popular is 0 then set it to 1 but if plan_id is any other value and plan_popular is 1 then set it to 0.
UPDATE {CI}Plans
SET plan_popular = if( plan_id = ?, 1, 0 )
where (plan_id = ? and plan_popular = 0)
or (plan_id <> ? and plan_popular = 1);
The where clause lets through only those rows that will actually be changed by the update. If this is a largish table, that can make quite a difference in response time. Logic is much less expensive than any actual operation that can performed in the database.