This question already has answers here:
With MySQL, how can I generate a column containing the record index in a table?
(8 answers)
Closed 8 years ago.
I have: Select some set of pairs. The first column is the id of row in table, the second is the new value which should be assigned to that row.
-- the first query
CREATE TABLE tmp;
SELECT row_id, new_value
FROM [not essential tables and joins]; //PSEUDOCODE
-- another queries
FOR EACH tmp //PSEUDOCODE
UPDATE table SET value = new_value WHERE id = row_id;
-- QUESTION: CAN I MERGE SELECT AND UPDATE IN ONE QUERY?
-- I want avoid creating temporary table.
Problem: Iteration through table (as in example above) decrease clearness and speed of code.
Question: *How to do the same in single query
I think you are looking for update the table join with other table (Not sure though). You can do something like
UPDATE tmp a
JOIN sometable b ON a.col = b.col
AND a.id = b.row_id
SET a.value = b.new_value
Related
This question already has answers here:
Avoid duplicates in INSERT INTO SELECT query in SQL Server
(11 answers)
Closed 1 year ago.
In sql I have one blank table and second one with values
In me second one I have column with values like
poland-data
russia-data
usa-data
england-data
poland-data-hr
england-data-hr
england-hr
poland-hr
I want to copy to the blank table column with values without 'hr' from table nr.2
for example i only want to see in that table
poland-data
russia-data
usa-data
england-data
You can try following approach:
SELECT distinct REPLACE(col1 ,'-hr', '') as col1
INTO TableTwo
FROM TableOne
It's not entirely clear what you are asking. Is this a specific case of something that will have to be done many times with variable columns? If not, you should be able to just to
CREATE TABLE TABLE_2 AS
SELECT poland_data,
russia_data,
usa_data,
england_data
FROM TABLE_1;
Or
INSERT INTO TABLE_2
SELECT poland_data,
russia_data,
usa_data,
england_data
FROM TABLE_1;
If you already have the table created.
I have a table t with columns id(primary key),a,b,c,d. assume that the columns id,a,b and c are already populated. I want to set column d =md5(concat(b,c)). Now the issue is that this table contains millions of records and the unique combination of b and c is only a few thousands. I want to save the time required for computing md5 of same values. Is there a way in which I can update multiple rows of this table with the same value without computing the md5 again, something like this:
update t set d=md5(concat(b,c)) group by b,c;
As group by does not work with update statement.
One method is a join:
update t join
(select md5(concat(b, c)) as val
from table t
group by b, c
) tt
on t.b = tt.b and t.c = tt.c
set d = val;
However, it is quite possible that any working with the data would take longer than the md5() function, so doing the update directly could be feasible.
EDIT:
Actually, updating the entire table is likely to take time, just for the updates and logging. I would suggest that you create another table entirely for the b/c/d values and join in the values when you need them.
Create a temp table:
CREATE TEMPORARY TABLE IF NOT EXISTS tmpTable
AS (SELECT b, c, md5(concat(b, c)) as d FROM t group by b, c)
Update initial table:
UPDATE t orig
JOIN tmpTable tmp ON orig.b = tmp.b AND orig.c = tmp.c
SET orig.d = tmp.d
Drop the temp table:
DROP TABLE tmpTable
I'm trying to update a certain column of certain row WHERE id is certain value. The thing is, the number/names of columns are variable, and so are their respective ids.
For example:
UPDATE table SET column1="hello" WHERE id = 5
UPDATE table SET column2="cucumber" WHERE id = 6
How can I do a single mysql query in PDO to do this?
First thing I tried is...
UPDATE table SET column1="hello", column4="bye" WHERE id IN(5, 6)
But that query will update BOTH of those columns in rows where it finds BOTH of those ids, and that's not what I'm looking for. Is it only possible to do this query by query?
Keep in mind that the argument after SET is variable, so the columns to be updated, their values and their respective ids are also variable.
A solution where you can just purely bind values would be great, but if I have to build the query string with escaped variables, then that's OK too.
Thank you.
You can do this
UPDATE table t1 JOIN table t2
ON t1.id= 5 AND t2.id= 6
SET t1.column1= 'hello',
t2.column2 = 'cucumber';
Or if you want to do this on a single column
UPDATE table
SET column2 = CASE id
WHEN 5 THEN 'hello'
WHEN 6 THEN ''
END
WHERE id IN(5, 6);
The accepted answer to sql swap primary key values fails with the error Can't reopen table: 't' - presumably this has something to do with opening the same table for writing twice, causing a lock.
Is there any shortcut, or do I have to get both, set one of them to NULL, set the second one to the first one, then set the first one to the previously fetched value of the second?
Don't use temporary tables for this.
From the manual:
You cannot refer to a TEMPORARY table more than once in the same query.
For example, the following does not work:
mysql> SELECT * FROM temp_table, temp_table AS t2;
ERROR 1137: Can't reopen table: 'temp_table'
This error also occurs if you refer to a temporary table multiple
times in a stored function under different aliases, even if the
references occur in different statements within the function.
UPDATE:
Sorry if I don't get it right, but why does a simple three way exchange not work?
Like this:
create table yourTable(id int auto_increment, b int, primary key(id));
insert into yourTable(b) values(1), (2);
select * from yourTable;
DELIMITER $$
create procedure pkswap(IN a int, IN b int)
BEGIN
select #max_id:=max(id) + 1 from yourTable;
update yourTableset id=#max_id where id = a;
update yourTableset id=a where id = b;
update yourTableset id=b where id = #max_id;
END $$
DELIMITER ;
call pkswap(1, 2);
select * from yourTable;
To swap id values of 1 and 2, I would use a SQL statement like this:
EDIT : this does NOT work on an InnoDB table, only works on a MyISAM table, per my testing.
UPDATE mytable a
JOIN mytable b ON a.id = 1 AND b.id = 2
JOIN mytable c ON c.id = a.id
SET a.id = 0
, b.id = 1
, c.id = 2
For this statement to work, the id value of 0 must not exist in the table, any unused value would be suitable... but to get this to work in a single SQL statement, you need to (temporarily) use a third id value.
This solution works for regular MyISAM tables, not temporary tables. I missed that this was being performed on a temporary table, I was confused by the error message you reported Can't reopen table:.
To swap id values 1 and 2 in a temporary table, I'd run three separate statements, again, using a temporary placeholder value of 0:
UPDATE mytable a SET a.id = 0 WHERE a.id = 1;
UPDATE mytable b SET b.id = 1 WHERE b.id = 2;
UPDATE mytable c SET c.id = 2 WHERE c.id = 0;
Edit: Fixed errors
I have a simple amateur question.
Table A(login_count) contains all existing userids and their login-count.
Table B(login4buy) contains specific userids and other information.
I want SQL to add the specific login-count from Table A to the specific userid in table B.
This is my try:
INSERT INTO orders_subset
SELECT login_count
FROM login4buy
WHERE login4buy.userid=orders_subset.userid
How can I put the count from Table A into Table B?
I think you want an UPDATE instead of an INSERT
UPDATE lb
SET lb.orders_subset = lc.login_count
FROM login4buy lb
INNER JOIN login_count lc
ON lb.userid = lc.userid
I think you need UPDATE, not INSERT:
UPDATE
orders_subset
JOIN
login4buy
ON login4buy.userid = orders_subset.userid
SET
login4buy.login_count = orders_subset.login_count ;