I have been going through many queries, but can't seem to find the right combination to get this to work. I get the error "You can't specify target table 't1' for update in FROM clause". I know MySQL doesn't like the subquery in the update statement and have read about wrapping it in other select statements, but can't seem to figure it out. Here is a stripped down query of what I am looking for:
UPDATE myTable t1 SET t1.num=concat(t1.num,'B') WHERE t1.num in ('1','2') and t1.expiry=(SELECT max(t2.expiry) from myTable t2 where t2.num=t1.num);
Basically trying to get the latest date (expiry) for each number (num) and change the number where applicable.
This should works :
UPDATE myTable t1, (SELECT num, max(expiry) expiry from myTable t2 group by num) t2
SET t1.num = concat(t1.num,'B')
WHERE t1.num in ('1','2')
and t1.expiry = t2.expiry
and t1.num = t2.num;
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 have a pretty simple MySQL query to implement, but I can't figure out how...
I have two tables, T1 and T2.
What I need to do:
From T1, I retrieve an ID based on a CODE value:
SELECT id FROM T1 WHERE code = '$code';
Then I need to use this ID (so the value I just retrieved) to update a specific row in T2 (the name of the row will match the ID's value).
I was thinking about using either subqueries or user-defined variables, but no matter how I try it I can't get it done.
If you have any code snippet that can help me doing that, I would appreciate it as well!
EDIT
Just to clarify something: I don't know the name of the column that I need to update in T2, since that name will be the value I retrieve from T1.
So for example, if the ID I get from T1 is "03", it will update the column named "03" in T2.
EDIT 2
Here's a little schema of what I intend to achieve (hoping I make myself clearer, I'm sorry for the misunderstanding...)
UPDATE T2 SET COL = YOUR_VALUE
WHERE T2.ID = (SELECT id FROM T1 WHERE code = '$code')
UPDATE: If the sub query returns more than one row then you can use from IN operator
UPDATE T2 SET COL = YOUR_VALUE
WHERE T2.ID IN (SELECT id FROM T1 WHERE code = '$code')
Use an UPDATE with a JOIN:
UPDATE T2
CROSS JOIN T1
SET T2.`0` = IF(T1.id = 0, T1.someColumn, T2.`0`),
T2.`1` = IF(T1.id = 1, T1.someColumn, T2.`1`),
T2.`2` = IF(T1.id = 1, T1.someColumn, T2.`1`)
WHERE T1.code = '$code'
Replace someColumn with the column in T1 containing the value you want to put into T2.
you can update without using the subquery just using join
update t2
inner join t1 on t2.name = t1.id and t1.code ='$code'
set t2.my_col = 'my_value'
but you should not use var in your query you are at risk for sql injection take a look at you mysql driver for param_binding
UPDATE T2 SET COL = YOUR_VALUE WHERE EXISTS
(SELECT 1 FROM T1 WHERE T2.id=T2.id AND code = '$code')
You can update T2 with the next SQL if you expect at least one row from the inner query
UPDATE T2 SET COLUMN = VALUE
WHERE T2.ID IN (SELECT ID FROM T1 WHERE CODE = $code)
Otherwise, if from T1 you are sure you will get only 1 record
UPDATE T2 SET COLUMN = VALUE
WHERE T2.ID = (SELECT ID FROM T1 WHERE CODE = $code)
I am trying to set a column value in MySQL based on the following query.
select * from table1 t1
join table2 t2
on t1.id = u.t1_id
and t2.status = 'verified'
and not exists (
select 1
from table2 t2_2
where t2.t1_id = t2_2.t1_id
and t2_2.updated_at > t2.updated_at
)
This query returns the results I want, but when I try to add
SET t1.column_k = 'some value'
to the end, I'm getting an error that simply says You've got a syntax error near set t1.column_k.... check manual corresponding to your version of MySQL.
I'd really like to know how to include a set on the results of this query and am having trouble formulating that. Any help or ideas?
It's difficult and confusing to me I think because of the self join. The eventual plan is to port this query w/the set command into a migration file in rails once I've got it working.
You need an update. Select isn't used for setting values.
update table1 t1 join
table2 t2
on t1.id = u.t1_id and
t2.status = 'verified' and
not exists (select 1
from table2 t2_2
where t2.t1_id = t2_2.t1_id and
t2_2.updated_at > t2.updated_at
)
set t1.column_k = 'some value';
I have the following query to update a table where the field is calculating as a rank based on a score field.
update `table` T1 set Rank=
(select count(*)+1 from (select * from `table` WHERE platform='asdf') T2
WHERE T2.score > T1.score AND T2.platform='asdf') WHERE T1.platform='asdf'
However, I want to set a difference field from the old rank which uses the previous rank to calculate (rankDiff=rank - f) where
f = ` (select count(*)+1 from (select * from `table` WHERE platform='asdf') T2
WHERE T2.score > T1.score AND T2.platform='asdf') WHERE T1.platform='asdf'`
Does anybody know a way I can do this? I was thinking of joining the table with the information but I can't get the JOIN ON part right with the count calculation (possible?).
Anyone have any ideas how this can be done without just straight up duplicating the code (which is an option, but not an elegent one!).
is this what you are trying to achieve:
update `table` T1 set Rank=(select count(*)+1 from (select * from `table`
WHERE platform='asdf') T2
WHERE T2.score > T1.score AND T2.platform='asdf') WHERE T1.platform='asdf' as NewRankew),
RankDiff=Rank-NewRank
I'm working on a query that uses having to compare a sum of elements from a joined table to a value of a field from the "main" table.
Here's the gist of my query:
SELECT t1.id
FROM table1 AS t1
INNER JOIN table2 t2 ON t2.t1_id = t1.id -- AND OTHER CONDITIONS
-- WHERE more t1 conditions
GROUP BY t1.id
HAVING SUM(t2.amount) <> t1.total_amount
AND SUM(t2.amount) = (t1.component1+t1.component2+t1.component3+t1.component4);
It outputs : ERROR 1054 (42S22): Unknown column 't1.total_amount' in 'having clause'
Needless to say, the field exists in t1 and there were no typos (quadra-checked this, on the brink of insanity here).
I can't for the life of me figure out what's wrong here. I tried searching SO already and most of the having problems are due to people using HAVING instead of WHERE, but seeing as I'm using SUM(), I think this is the right way to go.
EDIT: Terje's answer was the most accurate, although I did manage to pull it off without using that syntax in (possibly the most stupid update sentence of all time) my update sentence, which was (stupid, do not try this at home unless everything else fails):
UPDATE t1
SET t1.total_amount =
(
SELECT SUM(t2.amount)
FROM table 2
--WHERE, AND
GROUP BY t1.id
HAVING SUM(t2.amount) <> t1.total_amount
AND SUM(t2.amount) = (t1.component1+t1.component2+t1.component3+t1.component4)
)
WHERE t1.id IN (same awful subquery as before, except selecting t2.t1_id)
--AND other conditions
;
P.S. : The end goal here is to use the same having conditions in an update sentence
Bunch of thanks in advance,
-Lauri
In order to compare to t1.total_amount you will have to add it to the GROUP BYclause, or to compare to e.g. min(total_amount). As you are grouping by t1.id it does not matter what aggregate function of total_amount you are using.
HAVING and GROUP BY only works on things you are actually selecting, unlike the WHERE and ORDER BY clauses. So you need to select total_amount, I'm afraid. Also, the syntax is '!=' for unequal in MySQL. (I stand corrected, '<>' is fine in MySQL.)
Think of WHERE and ORDER BY as your manipulation of the tables you are selecting from, and HAVING and GROUP BY as manipulating the data you now have.