I have this query.
UPDATE messages
SET seen_by = CONCAT( seen_by, '3,')
WHERE id IN (SELECT id FROM messages WHERE NOT FIND_IN_SET(3, seen_by) AND chat_id = 350)
But when I try to execute it, it gives me this error
You can't specify target table 'messages' for update in FROM clause
I want to update the same table what I have used in my WHERE clause. How can I do that?
You don't even need a subquery.
Just replace WHERE id IN (SELECT id FROM messages WHERE xyz) by WHERE xyz.
This is more straight forward and doesn't have to first load all IDs into RAM (if it would even have allowed you).
Related
My problem is the following, I want set a list of ID in a variable, then use this variable in a subquery. The problem is that WorkBench (my GUI) return the following error : "subquery returning multiple rows". It seems to me that's what I want.
Please explain me where I am wrong.
This is my query :
set #listID := (select ID_VOIE as ID from voies
where ORIGINE = 'XXX'
group by CODE_INSEE, CODE_VOIE
having count(*) > 1);
select substring(v.CODE_INSEE,1,2), count(*) from voies v
where v.ID_VOIE in (#listID)
group by substring(vs.CODE_INSEE,1,2);
The thing is I'm blocked with the "group by", I want do a groupd by after a first group by, that's why I can't (or at least i didn't find a way) write the request with a single WHERE clause.
The thing is I know that I can put the whole request directly in my subquery instead of using variable but :
It can let me use this trick in another requests that needed this behaviour (DRY concept !)
I'm not sure but the subquery will be executed in each turn of my loop, and that will be very inefficient
So I seek 2 possible ways : a way that let me use a list in a variable in a subquery OR a way that let me use "group by" twice in a single query.
Thanks you in advance for your answers (oh and sorry for my english, this is not my maternal language).
Unless you need that variable for something else, you should be able to skip it entirely as follows:
SELECT
SUBSTRING(v.CODE_INSEE,1,2),
COUNT(*)
FROM
voies v
WHERE
v.ID_VOIE in
(SELECT
ID_VOIE as ID
FROM
voies
WHERE
ORIGINE = 'XXX'
GROUP BY
CODE_INSEE,
CODE_VOIE
HAVING COUNT(*) > 1)
GROUP BY
SUBSTRING(vs.CODE_INSEE,1,2);
As you say, the subquery will be executed for all rows. To avoid that, a variable would be best, but MySQL doesn't support table variables. Instead, you can use a temporary table:
IF EXISTS DROP TABLE myTempTable;
CREATE TEMPORARY TABLE myTempTable (ID_VOIE int); -- I don't know the datatype
INSERT INTO myTempTable (ID_VOIE)
SELECT DISTINCT -- using distinct so I can join instead of use IN.
ID_VOIE as ID from voies
WHERE
ORIGINE = 'XXX'
GROUP BY
CODE_INSEE, CODE_VOIE
HAVING COUNT(*) > 1
And now you can do this:
SELECT
SUBSTRING(v.CODE_INSEE,1,2), COUNT(*)
FROM
voies v
JOIN myTempTable tt ON
v.ID_VOIE = tt.ID_VOIE
GROUP BY SUBSTRING(vs.CODE_INSEE,1,2);
I'm trying to update a table through a query, the query itself is created using the results of queries to other tables (one of which is the table we are updating)...
However, I keep getting an error when I try to execute the query... After some research I found out I have to encase the inner query with a SELECT * FROM ()... but this doesn't seem to have worked...
I can't figure out how to bypass this error with my MySQL Query...
This is the error I'm getting...
[Err] 1093 - You can't specify target table 'players' for update in
FROM clause
This is my query...
DELETE FROM players WHERE name='Henry' AND player_group_id IN
(
SELECT id FROM playergroups WHERE player_set_id=
(
SELECT id FROM playersets WHERE player_name=
(
SELECT name FROM
(
SELECT name FROM players WHERE player_group_id=
(
SELECT id FROM playergroups WHERE player_set_id=
(
SELECT id FROM playersets WHERE player_name='Henry'
)
)
) AS P1
)
)
);
use joins, avoid to much use of nested statements
You should really find a better way to navigate though the tables, but where exists is a good way to around that error. Or you could stage off the data and delete based of PIs.
DELETE FROM players A
WHERE name = 'Henry'
AND WHERE EXISTS
(
SELECT 1
FROM playersgroup B
WHERE A.players_group_id = B.players_group_id
)
ETC.. ETC.. Depending on how many tables you need to reference.
I got two MySQL working fine and i'm trying to find a way to combine them into one single query.
First, it selects ID of an employee.
SELECT 'ID' FROM `employee` ORDER BY ID DESC LIMIT 1;
Let's say it returns ID 100;
Then update data of employees whose ID is 100
UPDATE 'LOG' SET `TIME_EXIT`='2013/02/22' WHERE `ID`='100';
Can i do it all in a single query?
Just add them together:
UPDATE LOG SET TIME_EXIT = '2013/02/22'
WHERE ID = (
SELECT ID
FROM employee
ORDER BY ID DESC
LIMIT
);
But based on that code currently it'll only ever update the last employee, you will need to select the correct employee by using some other identifier to ensure you have the correct one.
UPDATE LOG SET TIME_EXIT = '2013/02/22'
WHERE ID = (
SELECT ID
FROM employee
WHERE NAME = 'JOHN SMITH'
ORDER BY ID DESC
LIMIT 1
);
It's now a few months old, but maybe helps you or others finding this via google…
If you want to UPDATE a field in the same selected table use this:
UPDATE LOG SET
TIME_EXIT = '2013/02/22'
WHERE ID = (
SELECT ID
FROM (
SELECT ID
FROM LOG
WHERE whatEverYouWantToCheck = whateverYouNeed
) AS innerResult
)
So, you SELECT id from a subselect. If you try to subselect it directly, mySQL quites with your error message You can't specify target table 'log' for update in FROM clause, but this way you hide your subsubquery in a subquery and that seems to be fine. Don't forget the AS innerResult to avoid getting the error message #1248 - Every derived table must have its own alias. Also match the subsubquery field name to the subquery field name in case you do something like SELECT COUNT(*) or SELECT CONCAT('#', ID)
I have the database of ATM card in which there are fields account_no,card_no,is_blocked,is_activated,issue_date
Fields account number and card numbers are not unique as old card will be expired and marked as is_block=Y and another record with same card number ,account number will be inserted into new row with is_blocked=N . Now i need to update is_blocked/is_activated with help of issue_date i.e
UPDATE card_info set is_blocked='Y' where card_no='6396163270002509'
AND opening_date=(SELECT MAX(opening_date) FROM card_info WHERE card_no='6396163270002509')
but is doesn't allow me to do so
it throws following error
1093 - You can't specify target table 'card_info' for update in FROM clause
Try this instead:
UPDATE card_info ci
INNER JOIN
(
SELECT card_no, MAX(opening_date) MaxOpeningDate
FROM card_info
GROUP BY card_no
) cm ON ci.card_no = cm.card_no AND ci.opening_date = cm.MaxOpeningDate
SET ci.is_blocked='Y'
WHERE ci.card_no = '6396163270002509'
That's one of those stupid limitations of the MySQL parser. The usual way to solve this is to use a JOIN query as Mahmoud has shown.
The (at least to me) surprising part is that it really seems a parser problem, not a problem of the engine itself because if you wrap the sub-select into a derived table, this does work:
UPDATE card_info
SET is_blocked='Y'
WHERE card_no = '6396163270002509'
AND opening_date = ( select max_date
from (
SELECT MAX(opening_date) as_max_date
FROM card_info
WHERE card_no='6396163270002509') t
)
This is my mysql query, but it is not working
update jos_users set name =
(SELECT name
FROM jos_users
WHERE id = 478) where id =477
can any one please tell how to execute this query? or other possibility?
the error-message you should get is:
#1093 - You can't specify target table 'jos_users' for update in FROM clause
wich means you cant use the same table you're updating in a subselect. anywa, there's a litte workaround to avoid this: just use a nested subselect instead:
update
jos_users
set
name = (select name from
(SELECT name FROM jos_users WHERE id = 478)
AS subselect_value)
where
id = 477