MySQL if statement - mysql

I want to update all rows when invoiceID is NULL else update only the rows where all invoiceID's are the same.
My current SQL statement is as follows:
UPDATE Table SET strPOnummer = '123'
WHERE strPOnummer = '456' AND strPOnummer != '' AND strPOnummer IS NOT NULL
So, when Table.invoiceID is NULL, it should update all rows, else update only the rows where invoiceID is the same.

Assuming that invoiceID is an input parameter, you could do this:
UPDATE Table
SET strPOnummer = '123'
WHERE --your non-invoiceID filtering conditions go here
AND (Table.invoiceID = #InvoiceID OR #InvoiceID IS NULL)
In this case if the #InvoiceID parameter is not null then the first condition will have to be met as the second will never be met, but if it is null then each row of the table will be matched by the second part of the condition and thus the first one isn't relevant anymore

I will write just example not code to use, please modify it yourself as needed
SELECT IF(invoiceID=1,
(UPDATE table as tmp SET... WHERE tmp.id=table.id),
(UPDATE table as tmp SET... WHERE tmp.id=table.id)
) FROM table);

Related

Is it possible SET 'status' at other row false when NEW.status = true?

I have an AFTER UPDATE TRIGGER, that i want only one row that has status is TRUE. Here is my trigger,
CREATE TRIGGER check_true AFTER UPDATE ON table1 FOR EACH ROW
BEGIN
IF (NEW.status = 1) THEN
UPDATE table1 SET status = 0 WHERE id <> NEW.id;
END IF;
END
I try change status from 1 to 0 there is no error. But when I try change from 0 to 1 there is error like this,
Can't update table 'table1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger
Thanks in advance, sorry for my bad language.
A trigger cannot action the table it was fired upon, so what you want to do cannot be achieved with a trigger.
Another option would be to re-formulate your update queries so it updates all needed records at once, like:
update mytable
set status = case when id = :myid then :status else 0 end
where id = :myid or (status = 1 and :status = 1)
Here, :id and :status represent the query parameters.
The where clause selects records that match the :id parameter - if the new status is 1, it also selects existing records whose status is 1 (there should be only one).
Then, the set clause uses a case expression to update the status of the new record and reset the previous one (if any)
First, in MySQL 8+, you can have MySQL enforce the uniqueness.
alter table table1 add column status_true varchar(255) generated always as
(case when status then status end);
create unique index unq_table1_status_true on (status_true);
Now, the database ensures uniqueness.
You can update the value using a single update:
update table1
set status = not status
where status or id = 2
The "4" is the id you want to change to be the active one.
Here is a db<>fiddle.

MySQL: Update table with an IN (#variable) failed

I'm trying to update a table, with the IN function and a variable.
The content of the variable is a sub-query that returns the expected values aka ID for each STRING. When I copy/paste the values in the update, everything is fine.
USE `DB1`;
SET SQL_SAFE_UPDATES = 0;
SET #VAR1 = "STRING1,STRING2,STRING3,STRING4";
SET #VAR2 = (SELECT GROUP_CONCAT(`id`) FROM `tbl_A` WHERE FIND_IN_SET(`description`, #VAR1) AND `fieldtype` = '');
UPDATE `tbl_A`
SET `idaccount` = 2
WHERE `id` IN (#VAR2);
SET SQL_SAFE_UPDATES = 1;
So why when I use the variable, it updates only the first row?
The variable #VAR2 is a scalar variable, and can't store a result set. To do that, you would need a table variable, which MySQL does not directly support (note that other databases, such as SQL Server, do support them).
But, you may inline the subquery and it should work:
SET #VAR1 = "STRING1,STRING2,STRING3,STRING4";
UPDATE tbl_A
SET idaccount = 2
WHERE id IN (SELECT id FROM (
SELECT id FROM tbl_A
WHERE FIND_IN_SET(description, #VAR1) AND fieldtype = ''
)x );
Note that the subquery following the IN clause of the update is wrapped twice, to avoid the problem of trying to reference the same table which is being updated. This trick actually materializes the subquery, leaving it independent of what happens during the update.

Execution of UPDATE based on condition

Is there a way in MySQL to insert a condition based on which the entire UPDATE query will be executed? I know that you can use IF or CASE within the query itself to insert different values, but I'm talking about this scenario:
IF ( condition is true ) UPDATE ...
Let's say I wanted to validate data and execute the UPDATE based on result (I know it's a bad idea and data validation should be done scripting wise, I'm just reviewing the theoretical possibilities). Like here below where I test a value against regexp to check if it's numerical value:
UPDATE executed:
IF ( "12345" REGEXP "[0-9]+" ) UPDATE table SET numdata = "12345" WHERE...;
UPDATE not executed:
IF ( "a1234" REGEXP "[0-9]+" ) UPDATE table SET numdata = "a1234" WHERE...;
Thanks,
Prez
Just put the REGEXP in your WHERE clause:
DECLARE mynumdata varchar(10) = "a1234";
UPDATE table SET numdata = mynumdata
WHERE #numdata REGEXP "[0-9]+"
AND <other update conditions>;
One way to do this would be to add the condition to the WHERE clause.
So if you originally had
UPDATE table SET numdata = "a1234" WHERE id=1
you could write this as
UPDATE table SET numdata = "a1234" WHERE id=1 AND "1234" REGEXP "[0-9]+"

UPDATE (B) from (A) if (B) = 0?

I'm learning this for school and I'm confused. I'm trying to copy information between columns in a single table in a single db, all local.
Basically:
(I need to loop through and update all records)
UPDATE `my_records`
SET `realname` = `name`
WHERE `realname` = 0;
SELECT * FROM `my_records` SET `realname` = `name` WHERE `realname` = 0;
It keeps telling me I have a syntax error.
I now see why they are asking me to learn this. Each row in the table is different so when I update all columns some rows change that shouldn't so that's not the end result I'm after. I can try to give an example but this is confusing to me.
DB -> Table -> Row 1 - holds the name of the person -> Row 2 - holds the picture
of the person
Both things have a name (example Row 1 David, Row 2 Flower.JPG)
So I'm guessing they want me to figure out a way to exclude updating the 'real_name' column on Row 2 where the image is a JPG, GIF, or PNG.
I think the final result they are looking for when the table is updated is:
Row 1 'David' 'David'
Row 2 'flower.jpg'
Then this loops over and over again for all the records.
You need to use an UPDATE instead of a SELECT. SELECT statements only return data, they do not modify data.
So, to return the records you will update in the next step:
SELECT `realname`, `name` FROM `my_records` WHERE `realname` = 0;
and then to update those records:
UPDATE `my_records` SET `realname` = `name` WHERE `realname` = 0;
Note that this query will update the entire table, setting any row where the value of realname is equivalent to 0, to the value of that same row's name column.
A few other possibly useful statements:
UPDATE `my_records` SET `realname` = `name` WHERE `realname` = '';
This will affect all rows where realname is equivalent to 'empty string'
UPDATE `my_records` SET `realname` = `name` WHERE `realname` IS NULL;
will affect all rows where realname is NULL

if value is not empty, then insert mysql

I have a table in mysql like this (the id is primary key):
id | name | age
1 | John | 46
2 | | 56
3 | Jane | 25
Now I want to update the name only if this is empty. If the value is not empty it should duplicate the row with a new id else it should update the name.
I thought it could be done with an if-statement but it doesn't work.
if((select `name` from `table1` where `id` = 3) = '',
update `table1` set `name`='ally' where `id` = 3,
insert into `table1` (`id`,`name`,`age`) values
(4, 'ally', select `age` from `table1` where `id` = 3))
EDIT:
With Spencers answer I made it working using an if in the code. (However I would still like a way to do just a single mysql query).
db.set_database('database1')
cursor = db.cursor()
query = "select IF(CHAR_LENGTH(name)>0,1,0) from table1 where id = {0}".format(id)
cursor.execute(query)
val1 = cursor.fetchone()
if val1[0]:
query = "INSERT INTO `table1` (`id`,`name`,`age`) SELECT {0},{1},`age` FROM `table1` WHERE `id` = {2}".format(new_id, name, id)
cursor.execute(query)
else:
query = "update `table1` set `name` = '{0}' where `id` = {1}".format(name, id)
cursor.execute(query)
db.commit()
If you make like this :
select t.*,
if(
EXISTS(select n.name from table1 n where n.id = 2 and NULLIF(n.name, '') is null) ,
'true',
'false'
) from table1 t
if statement returns "true", becouse in your table exist row where id =2 and name is empty.
like this example, You can edit your query :
if(
EXISTS(select n.name from table1 n where n.id = 3 and NULLIF(n.name, '') is null),
update `table1` set `name`='ally' where `id` = 3,
insert into `table1` (`id`,`name`,`age`) values
(4, 'ally', select `age` from `table1` where `id` = 3)
)
IF is not a valid MySQL statement (outside the context of a MySQL stored program).
To perform this operation, you'll need two statements.
Assuming that a zero length string and a NULL value are both conditions you'd consider as "empty"...
To conditionally attempt an update of the name field, you could do something like this:
UPDATE table1 t
SET t.name = IF(CHAR_LENGTH(t.name)>0,t.name,'ally')
WHERE t.id = 3 ;
The IF expression tests whether the current value of the column is "not empty". If it's not empty, the expression returns the current value of the column, resulting in "no update" to the value. If the column is empty, then the expression returns 'ally'.
And you'd need a separate statement to attempt an INSERT:
EDIT
This isn't right, not after a successful UPDATE... of the existing row. The attempt to INSERT might need to run first,
INSERT INTO table1 (id,name,age)
SELECT 4 AS id, 'ally' AS name, t.age
FROM table1 t
WHERE t.id = 3
AND CHAR_LENGTH(t.name)>0;
We need a conditional test in the WHERE clause that prevents a row from being returned if we don't need to insert a row. We don't need to insert a row if the value 'ally' ...
The use of CHAR_LENGTH >0 is a convenient test for string that is not null and is not zero length. You could use different test, for however you define "empty". Is a single space in the column also considered "empty"?)