I have a table in with a unique id column, a non-unique name column, and other irrelevant columns. I want to update rows of data based off a single id. I've tried:
UPDATE mytable SET myfield = 'blah' WHERE name IN (SELECT name FROM mytable WHERE id = 1613)
But that gives this error Table 'mytable' is specified twice, both as a target for 'UPDATE' and as a separate source for data
Then I tried:
UPDATE mytable SET myfield = 'blah' WHERE name IN (SELECT name WHERE id = 1613)
The problem with this is that it is only affecting 1 row, even though there are multiple rows that have the same name.
I know how to accomplish this by using 2 different queries. One to fetch the name, and the other to update rows using that name. But is there a way to do this with just 1 query?
You can join tables to update them :
UPDATE mytable t1 inner join mytable t2 on t1.name = t2.name SET t1.myfield = 'blah' where t2.id = 1613
When you try to update the same table as you a re getting the right amount of rows, the result set can change every row that is updated. that is not possible.
solution make a temporary table as below
UPDATE mytable SET myfield = 'blah' WHERE name IN (SELECT name FROM (SELECT * FROM mytable) t1 WHERE id = 1613)
Related
I'm trying to update a column of a table so that is equal to the count of something in another table. Like this:
UPDATE TABLE
SET TOTAL = (SELECT COUNT(f1)
FROM TABLE2
GROUP BY f2);
But I keep getting sub query returns more than 1 row, and I can't think of how to fix it.
UPDATE (copied from the comment)
f2 is the relation between TABLE and TABLE2 – Thomasd d
Based on your comment
f2 is the relation between TABLE and TABLE2
you probably want something like this
UPDATE TABLE T1, (SELECT f2, COUNT(F1) cnt FROM TABLE2 GROUP BY f2) T2
SET T1.TOTAL = T2.cnt
WHERE T1.f2=T2.f2
adapt T1.f2 if necessary
UPDATE t1
SET total = ( SELECT COUNT(f1)
FROM t2
WHERE t1.f2 = t2.f2 );
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=91de17deff657f66fa54b42fe20ed3c5
Add WHERE total IS NULL if you do not need to recalculate values for rows which have a value already.
Your subquery is returning multiple values and your SET statement is only expecting one. This might fix your code if that is what you are looking for.
UPDATE TABLE
SET TOTAL = (SELECT COUNT(f1)
FROM TABLE2)
I'm trying to update a yes/no column in a table based on a lack of matches from a second table as follows:
UPDATE Table1
INNER JOIN Table2
ON (Table1.Date_last_action = Table2.MaxOfDate_last_action)
AND (Table1.Office = Table2.Office)
AND (Table1.Response_ID = Table2.Response_ID)
SET Table1.IsDeprectated = 1
WHERE (([Table2].[MaxOfDate_last_action] Is Null));
OR
UPDATE Table1
INNER JOIN Table2
ON (Table1.Date_last_action <> Table2.MaxOfDate_last_action)
AND (Table1.Office = Table2.Office)
AND (Table1.Response_ID = Table2.Response_ID)
SET Table1.IsDeprectated = 1;
Neither of which is working.
What I'm aiming for is that when the update query is executed that the IsDeprecated column is set to True for all rows in Table1 that DO NOT have a matching row in Table2
Is this possible?
[Edit following Tim's comment]
You could use exists logic along with a subquery:
UPDATE Table1 t1
SET t1.IsDeprectated = 1
WHERE NOT EXISTS (SELECT 1 FROM Table2 t2
WHERE t1.Date_last_action <> t2.MaxOfDate_last_action AND
t1.Office = t2.Office AND
t1.Response_ID = t2.Response_ID);
I'm trying to delete duplicate rows from a mysql table, but still keep one.
However the following query seemingly deletes every duplicate row and I'm not sure why. Basically I want to delete the row if the outputID, title and type all matches.
DELETE DupRows.*
FROM output AS DupRows
INNER JOIN (
SELECT MIN(Output_ID) AS Output_ID, Title, Type
FROM output
GROUP BY Title, Type
HAVING COUNT(*) > 1
) AS SaveRows
ON SaveRows.Title = DupRows.Title
AND SaveRows.Type = DupRows.Type
AND SaveRows.Output_ID = DupRows.Output_ID;
Just :
DELETE DupRows
FROM output AS DupRows
INNER JOIN output AS SaveRows
ON SaveRows.Title = DupRows.Title
AND SaveRows.Type = DupRows.Type
AND DupRows.Output_ID > SaveRows.Output_ID
This will delete all duplicates on Title and Type while keeping the record with the lowest value.
If you are running MySQL 8.0, you can use window function ROW_NUMBER() to assign a rank to each record in Title/Type groups, ordered by id. Then you can delete all records whose row number is not 1.
DELETE FROM output
WHERE Output_ID IN (
SELECT Output_ID
FROM (
SELECT Output_ID, ROW_NUMBER() OVER(PARTITION BY Title, Type ORDER BY Output_ID) rn
FROM output
) x
WHERE rn > 1
)
Delete From output Where Output_ID NOT IN (
Select MIN(Output_ID) from output Group By Title, Type Having COUNT(*)>1
)
By below query duplicate rows with matching condition get deleted and keeps one oldest unique row.
NOTE:- In my query I used id column is auto increment column.
DELETE t1
FROM output t1, output t2
WHERE t1.Title = t2.Title
AND t1.Type = t2.Type
AND t1.Output_ID = t2.Output_ID
AND t1.id>t2.id
If you want to keep newly inserted unique row just change the last condition as:
DELETE t1
FROM output t1, output t2
WHERE t1.Title = t2.Title
AND t1.Type = t2.Type
AND t1.Output_ID = t2.Output_ID
AND t1.id<t2.id
I want to update a certain record of a table only if certain another record does not already exist in the table.
I tried a SQL similar to following.
update mytable
set val = 'someval'
where id = 'someid' and
0 = (select count(*) from mytable where col='val2');
This fails with following error.
You can't specify target table 'mytable' for update in FROM clause
Only one process is updating this table, so preserving the atomicity of the operation is not necessary.
I know I can do this using two SQL queries, but is there a way to do this in a single query?
Because you are referring to the same table, the best way to do this uses LEFT JOIN:
update mytable t left join
mytable t2
on t2.col = 'val2'
set val = 'someval'
where t.id = 'someid' and t2.col is null;
There are several ways to do this. Here's one option using a subquery with not exists:
update mytable
set val = 'someval'
where id = 'someid'
and not exists (
select 1
from (select * from mytable) t
where col = 'val2')
SQL Fiddle Demo
Using the subquery bypasses the error you are receiving. Other approaches include outer join with null checks or using not in -- depends a bit on the data.
TRY this:
UPDATE mytable SET val = 'someval'
WHERE id = 'someid' AND col <> 'val2'
I use a MySQL DB, and I would like to update a field in a table based on another. Something like:
UPDATE table1
SET field1 = table2.id
WHERE field2 IN (
SELECT table2.name
FROM table2
);
I know that this query wouldn't work, but here is the idea. Is that even possible to do?
You can use a correlated sub query as below. This assumes there will be exactly one matching value returned. It will raise an error if more than one matching value is returned or set the field to null if zero are returned. If that last behaviour isn't desirable you will need a where clause.
UPDATE table1
SET field1 = (SELECT DISTINCT table2.ValueColumn
FROM table2
WHERE table2.JoinColumn = table1.JoinColumn)
Edit
To review records with 0 or more than 1 matches you could use
SELECT table1.JoinColumn, COUNT(DISTINCT table2.ValueColumn)
FROM table1
LEFT JOIN table2
ON table2.JoinColumn = table1.JoinColumn
GROUP BY table1.JoinColumn
HAVING COUNT(DISTINCT table2.ValueColumn) <> 1