Select updated records in mysql - mysql

How can I select Ids of updated records in mysql;
Is there any way to do something like this
select Id from (update tblA set col1=false where col2 > 5 )

You can't, you have to select them before updating.
If your table uses InnoDB storage engine, use SELECT FOR UPDATE to lock selected rows and prevent other clients from inserting, updating or deleting selected rows.
START TRANSACTION;
SELECT id FROM tblA WHERE col2 > 5 FOR UPDATE;
UPDATE tblA SET col1 = false WHERE col2 > 5;
COMMIT;
Another alternative is to set some column to a value which is unique to your client (e.g. process id) and when select using that value.
But it requires an additional column.
UPDATE tblA SET col1 = false, process_id = 12345 WHERE col2 > 5 AND process_id IS NULL;
SELECT id FROM tblA WHERE process_id = 12345

Related

Use values from adjacent rows in different columns of a mysql table

Table mytable in mysql has columns col1 and col2 with integer not null values. It also has a primary key id. After arranging the columns in a certain order, I need to calculate a certain sum from all the elements of columns col1 and col2 as follows: For a given value in col2 in a given row, compare it with the value of col1 in the next row. Take the smaller of these two values and subtract from it the value of col1 in the row where the value of col2 was taken; for the last row just subtract from the value in col2 the value in col1 in that row. Get the sum of all these differences.
I have the following solution which seems to work but might disturb where the user lacks privileges to create tables or alter the table structure. It would require checking existence of a table and some columns before they are created, besides needing to clean up after running, to remove the columns added.
alter table mytable add my_id int(5) not null;
alter table mytable add col3 int(7) not null;
SET #count = 0;
UPDATE mytable SET my_id = #count:= #count + 1;
create temporary table mytable2 as select my_id, col1 from mytable limit 1, 99999;
update mytable a join mytable2 b on a.my_id = (b.my_id - 1) set a.col3 = b.col1;
update mytable set col3 = col2 order by my_id desc limit 1;
select sum(LEAST(col2,col3) - col1) from mytable;
The Question: What would be a better way of getting the desired sum described above?
Here is some sample data:
id col1 col2
--------------------
11 609 618
42 620 628
23 624 630
34 627 637
Required Sum: (618-609) + (624-620) + (627-624) + (637-627) = 26

How to query a DBName if a column in a table has some specific value

eImagine this is your database structure when you connect to your server. Most of the time you will have same tables but the values are different. I want to query the Database name if one of the value for my table i.e Tbl1 ColumnName Col1 has value equal to 'Accepted'.
DbName1
Tbl1
Col1 -- 'Accepted' // this are the values col1 holds
-- 'Rejected'
-- 'In Process'
-- 'Awaiting Processing'
DbName2
Tbl1
Col1 -- 'NotAccepted'
-- 'Rejected'
DbName3
Tb1
Col1 -- 'NotAccepted'
-- 'Awaiting Processing'
DbName4
Tbl1
Col1 -- 'Accepted'
-- 'Rejected'
Expected Result
DbName1
DbName4 -- since both DB has Table name Tbl1 whose column Col1 = 'Accepted'
In my Sql Environment i have at least 37 Database.
Thank you very much for all your help.
If you know the database names and tables names and also the column names you can use a UNION solution like this:
SELECT distinct dbname
FROM (
select 'DbName1' as dbname, col1 from DbName1.tb1
union all
select 'DbName2' as dbname, col1 from DbName2.tb1
union all
select 'DbName3' as dbname, col1 from DbName3.tb1
union all
select 'DbName4' as dbname, col1 from DbName4.tb1
) dbs
WHERE dbs.col1 = 'Accepted';
Although this query will work you should really consider in having a better normalized database instead of 4 (or maybe more) with the same structure and data.

How to MERGE records in MYSQL

I'm able to use MERGE statement in both Oracle and MSSQL. Right now I have to use MYSQL. Does MYSQL has similar statement to merge data.
Lets say I have two tables:
create table source
(
col1 bigint not null primary key auto_increment,
col2 varchar(100),
col3 varchar(50)
created datetime
)
create table destination
(
col1 bigint not null primary key auto_increment,
col2 varchar(100),
col3 varchar(50)
created datetime
)
Now I want move all data from "source" to "destination". If record already exists in "destination" by key I need update, otherwise I need insert.
In MSSQL I use the following MERGE statement, similar can be used in ORACLE:
MERGE destination AS TARGET
USING(SELECT * FROM source WHERE col2 like '%GDA%') AS SOURCE
ON
(TARGET.col1 = SOURCE.col1)
WHEN MATCHED THEN
UPDATE SET TARGET.col2 = SOURCE.col2,
TARGET.col3 = SOURCE.col3
WHEN NOT MATCHED THEN
INSERT INTO
(col2,col3,created)
VALUES
(
SOURCE.col2,
SOURCE.col3,
GETDATE()
)OUTPUT $action INTO $tableAction;
WITH mergeCounts AS
(
SELECT COUNT(*) cnt,
MergeAction
FROM #tableAction
GROUP BY MergeAction
)
SELECT #Inserted = (SELECT ISNULL(cnt,0) FROM mergeCounts WHERE MergeAction = 'INSERT'),
#Updated = (SELECT ISNULL(cnt,0) FROM mergeCounts WHERE MergeAction = 'UPDATE'),
#Deleted = (SELECT ISNULL(cnt,0) FROM mergeCounts WHERE MergeAction = 'DELETE')
so here I'm update records if exists and insert if new record. After MERGE statement I also able to count how many records was inserted, updated ...
Does it possible to have such implementation in MYSQL ??
Mysql has insert ... on duplicate key update ... syntax. use it like this:
insert into destination(col1, col2, col3, created)
select *
from source
on duplicate key update
col2 = values(col2),
col3 = values(col3),
created = values(created);
demo here
to get the number of affected rows, run select row_count() afterwards

Mysql join few queries in one?

Can I combine two queries like this
first: UPDATE table SET col1=1 WHERE id='x';
second: UPDATE table SET col1=0 WHERE id='y';
can I join these queries in one?
UPDATE table
SET col1 = CASE id WHEN 'x' THEN 1 ELSE 0 END
WHERE id IN ('x','y')
Use this sql query:
UPDATE table
SET col1 =
CASE id
WHEN 'x' THEN 1
WHEN 'y' THEN 0
END
WHERE id IN ('x','y');
Also see Multiple Updates in MySQL
UPDATE table
SET col1 = (id = 'x')
WHERE id IN ('x','y');

MySQL Single Table Scan Update

Is there a way to accomplish a single table scan in MySQL with an UPDATE? The following is a standard example:
IF EXISTS (SELECT * FROM Table1 WHERE Column1='SomeValue')
UPDATE Table1 SET (...) WHERE Column1='SomeValue'
ELSE
INSERT INTO Table1 VALUES (...)
This is the ideal situation I'd like to happen in MySQL (But this is MsSQL):
UPDATE user SET (name = 'jesse') WHERE userid ='10001'
IF ##ROWCOUNT=0
INSERT INTO user (name) VALUES('jeeeeee')
It's sort of reversed in MySQL. You perform the insert, and if the key already exists, then update the row:
INSERT INTO Table1 (col1,col2,col3) VALUES (val1,val2,val3)
ON DUPLICATE KEY UPDATE col1 = val1, col2 = val2, col3 = val3;
This is predicated on you having a unique key for the table (which you do, right?)