MYSQL Updating multiple fields from fields of another table - mysql

Scenario:
I have an application that has a config table which stores the config data for each website thats uses the application. I have added a couple of extra columns to the config table and rolled this out to all applications. I have since updated these new columns with data that needs to be the same on all the config tables.
How would I go about doing this?
My first thought would be to duplicate the table and do the following:
UPDATE `config` SET `config`.`new1` = `tmp_config`.`new1`, `config`.`new2` = `tmp_config`.`new2` LEFT JOIN `tmp_config` ON (`tmp_config`.`tmp_id` = `config`.`id`)
Would this have the desired affect.

The following has worked for me (USING an INNER join and moving the SET to the end of the query:
UPDATE `config` INNER JOIN `tmp_config` ON (`tmp_config`.`id` = `config`.`id`)
SET `config`.`new1` = `tmp_config`.`new1`, `config`.`new2` = `tmp_config`.`new2`
Thanks for all your help!

I don't quite understand all of your question. Where have you changed the config? I read your explanations as:
You have changed the schema for all applications
You have updated the applications' configurations elsewhere
See VolkerK's answer for the correct syntax for multi-table updates.
Which storage engine are you using? If it's InnoDb (or other engine that supports transactions), you should start a transaction before running the query. Then you can verify that the result is the desired one before you commit any changes:
Example:
mysql> START TRANSACTION;
mysql> SELECT * FROM Configs LIMIT 5; -- See what it looks like before
mysql> Run update query here
mysql> SELECT * FROM Configs LIMIT 5; -- Verify that the result is the expected one
mysql> COMMIT;

This should have the effect of updating new1 and new2 in config to the values of new1 and new2 in tmp_config where ever the ids from the two tables match (and null if there is no match in tmp_config).
I believe that's what you said you are trying to do.
From the MySql update reference:
You can also perform UPDATE operations
covering multiple tables. However, you
cannot use ORDER BY or LIMIT with a
multiple-table UPDATE. The
table_references clause lists the
tables involved in the join. Its
syntax is described in Section
12.2.8.1, “JOIN Syntax”. Here is an example:
UPDATE items,month SET
items.price=month.price WHERE
items.id=month.id;
In this case they're not using just the "JOIN" syntax, but the JOIN syntax should still be valid, you just need to do it prior to the SET clause.
It would look something like
UPDATE `config`
LEFT JOIN `tmp_config` ON (`tmp_config`.`tmp_id` = `config`.`id`)
SET `config`.`new1` = `tmp_config`.`new1`, `config`.`new2` = `tmp_config`.`new2`

you need to do like :
edit
CREATE TABLE newtable SELECT * FROM oldtable;
MySQL creates new columns for all elements in the SELECT. For example:
mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY (a), KEY(b))
-> TYPE=MyISAM SELECT b,c FROM test2;

The multi-table update syntax doesn't allow a JOIN where you put it, see http://dev.mysql.com/doc/refman/5.0/en/update.html
UPDATE
config, tmp_config
SET
config.new1 = tmp_config.new1,
config.new2 = tmp_config.new2
WHERE
tmp_config.tmp_id = config.idshould do the trick (untested, no warranty ;-))

Related

How to use IF EXISTS to check whether table exists before removing data in that table

I wanted to check whether a table exists before deleting the values inside the table. In SQL Server we can do as simple as so :
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'table_to_be_edited')
BEGIN
DELETE FROM table_to_be_edited;
END;
but how do we do it in MySQL ?
I am using MySQL Workbench V8.0.
When delete an option is to ignore the table not found error. This eliminates race conditions where a table is created between the test and the truncate. Always consider this when doing SQL operations.

Check if record exists delete it using mysql

i'm using MySQL and i want to check if a record exists and if it exists delete this record.
i try this but it 's not working for me:
SELECT 'Barcelone' AS City, EXISTS(SELECT 1 FROM mytable WHERE City = 'Barcelone') AS 'exists';
THEN
DELETE FROM mytable
WHERE City = 'Barcelone';
Thank you for your help.
The if statement is only allowed in stored procedures, stored functions, and triggers (in MySQL).
If I understand what you want, just do:
DELETE FROM mytable
WHERE City = 'Barcelone';
There is no reason to check for the existence beforehand. Just delete the row. If none exist, no problem. No errors.
I would recommend an index on mytable(city) for performance reasons. If you want to check if the row exists first, that is fine, but it is unnecessary for the delete.
If you mean MySQL is returning an error message (if that's what you mean by "not working for me"), then that's exactly the behavior we would expect.
That SQL syntax is not valid for MySQL.
If you want to delete rows from a table, issue a DELETE statement, e.g.
DELETE FROM mytable WHERE City = 'Barcelone'
If you want to know how many rows were deleted (if the statement doesn't throw an error), immediately follow the DELETE statement (in the same session) with a query:
SELECT ROW_COUNT()
Or the appropriate function in whatever client library you are using.
If the ROW_COUNT() function returns 0, then there were no rows deleted.
There's really no point (in terms of MySQL) in issuing a SELECT to find out if there are rows to be deleted; the DELETE statement itself will figure it out.
If for some reason your use case requires you to check whether there are rows be be deleted, then just run a separate SELECT:
SELECT COUNT(1) FROM mytable WHERE City = 'Barcelone'

MySQL - Select and Update in a single command

I need to select a transactionID from a MySQL table and immediately increment it.
SELECT transid FROM idtable;
UPDATE idtable SET transid=transid +1;
I would like to combine the queries but cannot get the correct syntax.
Using a WHERE clause in your UPDATE will have the same effect.
UPDATE table
SET column = column + 1
WHERE column = value
You could use a sub-query style approach, but I have to wonder if there's any need for the initial SELECT. (Can't you just use a WHERE clause on the UPDATE, perhaps involving a multiple table join if so required.)
Take a look at the MySQL UPDATE query syntax for more information.

SQL (mySQL) update some value in all records processed by a select

I am using mySQL from their C API, but that shouldn't be relevant.
My code must process records from a table that match some criteria, and then update the said records to flag them as processed. The lines in the table are modified/inserted/deleted by another process I don't control. I am afraid in the following, the UPDATE might flag some records erroneously since the set of records matching might have changed between step 1 and step 3.
SELECT * FROM myTable WHERE <CONDITION>; # step 1
<iterate over the selected set of lines. This may take some time.> # step 2
UPDATE myTable SET processed=1 WHERE <CONDITION> # step 3
What's the smart way to ensure that the UPDATE updates all the lines processed, and only them? A transaction doesn't seem to fit the bill as it doesn't provide isolation of that sort: a recently modified record not in the originally selected set might still be targeted by the UPDATE statement. For the same reason, SELECT ... FOR UPDATE doesn't seem to help, though it sounds promising :-)
The only way I can see is to use a temporary table to memorize the set of rows to be processed, doing something like:
CREATE TEMPORARY TABLE workOrder (jobId INT(11));
INSERT INTO workOrder SELECT myID as jobId FROM myTable WHERE <CONDITION>;
SELECT * FROM myTable WHERE myID IN (SELECT * FROM workOrder);
<iterate over the selected set of lines. This may take some time.>
UPDATE myTable SET processed=1 WHERE myID IN (SELECT * FROM workOrder);
DROP TABLE workOrder;
But this seems wasteful and not very efficient.
Is there anything smarter?
Many thanks from a SQL newbie.
There are several options:
You could lock the table
You could add an AND foo_id IN (all_the_ids_you_processed) as the update condition.
you could update before selecting and then only selecting the updated rows (i.e. by processing date)
I eventually solved this issue by using a column in that table that flags lines according to their status. This column let's me implement a simple state machine. Conceptually, I have two possible values for this status:
kNoProcessingPlanned = 0; #default "idle" value
kProcessingUnderWay = 1;
Now my algorithm does something like this:
UPDATE myTable SET status=kProcessingUnderWay WHERE <CONDITION>; # step 0
SELECT * FROM myTable WHERE status=kProcessingUnderWay; # step 1
<iterate over the selected set of lines. This may take some time.> # step 2
UPDATE myTable SET processed=1, status=kNoProcessingPlanned WHERE status=kProcessingUnderWay # step 3
This idea of having rows in several states can be extended to as many states as needed.

Existence confirmation method of the table of MySQL

I want to confirm whether there is a certain table.
When create a table, there is an SQL sentence such as DROP TABLE IF EXISTS xxx_tb.
Will there be the method that can identify the existence of the table by SQL likewise?
Use INFORMATION_SCHEMA:
select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'MyTable';
Should be portable across most databases.
You want the SHOW TABLES command of MySQL:
SHOW TABLES LIKE 'xxx_tb';
Or indeed, you can just do a query like
SELECT COUNT(*) FROM tbl WHERE 1=0
Which will give an error (see documentation for exact error code, or try it) if the table doesn't exist, but succeed with no results if it does.