Output of select query in where clause not working - mysql

Update table set Style='new' where id=(SELECT MAX(id) From table);
This is my query. But not working in mysql.
Error shows: You can't specify target table 'table' for update in FROM clause
Please help.

You can store the result of the subquery in a session variable, like so:
SELECT MAX(id) INTO #maxID
FROM table
;
UPDATE table
SET Style='new'
WHERE id=#maxID
;
Note that the operation is no longer "atomic"; depending on the activity going on, it is potentially possible for that MAX(id) to change between the SELECT and the UPDATE.
Another possibility is:
UPDATE table
SET Style = 'new'
ORDER BY id DESC
LIMIT 1
;
But I tend to (for no particular reason) be averse to such queries.

Related

Select and update same table and row in one connection in mysql

This may seem like a repeat question, but it always seems to be questions involving more than one table. When a row in a table is selected, I will also need to +1 the view count in the same row. I know I can't use a trigger or two statements in the same query, but could both of these things be done with a single connection to the database? What would the preferred method be to both select a row and then +1 the view field?
It can be done in the same connection, but I can't think of a way for that to be done using one query.
Here is how you would do that in a single transaction;
START TRANSACTION;
UPDATE tbl SET view=view+1 WHERE id = 10;
SELECT * FROM tbl WHERE id = 10;
COMMIT;
A second "better" method you can do that which eliminates having to read the tbl table twice.
UPDATE tbl
SET view = (#viewsCount := view + 1)
WHERE id = 10;
And to get the new value of the views count I would do something like this
SELECT #viewsCount;
A third way would be by utilizing the LAST_INSERT_ID() function like so
UPDATE tbl
SET view = LAST_INSERT_ID(view) + 1
WHERE id = 10;
Then to get the new view count you will need to execute this query immediately after the update. you can not execute any other queries after the update otherwise you will not get the intended value.
SELECT LAST_INSERT_ID();

MySQL UPDATE on SELECT

In MySQL, is it possible to update the selected records on the same query?
For eg., If the query
SELECT *
FROM `table`
WHERE field = "value"
LIMIT 0,2
Return two rows, then on the same query, i need to increment the table's count field by 1. Is it possible?
Yes its possible you can write as UPDATE query as:
UPDATE my_table
SET count = count + 1
WHERE field = "value"
LIMIT 2;
or for LIMIT with offset try:
UPDATE my_table a
INNER JOIN (SELECT id FROM my_table WHERE field = "value" LIMIT 0, 2) b
ON a.id = b.id
SET count = count + 1;
It's not possible. The verb SELECT only retrieves data (without modifying it); and the verb UPDATE only modifies data (without retrieving it). There is no MySQL verb that will perform both actions. You will have to use two separate statements.
However, those two statements can be encapsulated within a transaction (if supported by your storage engine) to ensure that they are conducted atomically and/or could be invoked from within a stored procedure to simplify the command that must be issued by your client. Combining the two one would have:
DELIMITER ;;
CREATE PROCEDURE select_and_update(value TEXT)
BEGIN
START TRANSACTION;
SELECT * FROM `table` WHERE field = value LIMIT 0,2;
UPDATE `table` SET count = count + 1 WHERE ...;
COMMIT;
END;;
DELIMITER ;
Then your client need merely do:
CALL select_and_update('value');

MySQL: return updated rows

I am trying to combine these two queries in twisted python:
SELECT * FROM table WHERE group_id = 1013 and time > 100;
and:
UPDATE table SET time = 0 WHERE group_id = 1013 and time > 100
into a single query. Is it possible to do so?
I tried putting the SELECT in a sub query, but I don't think the whole query returns me what I want.
Is there a way to do this? (even better, without a sub query)
Or do I just have to stick with two queries?
Thank You,
Quan
Apparently mysql does have something that might be of use, especially if you are only updating one row.
This example is from: http://lists.mysql.com/mysql/219882
UPDATE mytable SET
mycolumn = #mycolumn := mycolumn + 1
WHERE mykey = 'dante';
SELECT #mycolumn;
I've never tried this though, but do let me know how you get on.
This is really late to the party, but I had this same problem, and the solution I found most helpful was the following:
SET #uids := null;
UPDATE footable
SET foo = 'bar'
WHERE fooid > 5
AND ( SELECT #uids := CONCAT_WS(',', fooid, #uids) );
SELECT #uids;
from https://gist.github.com/PieterScheffers/189cad9510d304118c33135965e9cddb
You can't combine these queries directly. But you can write a stored procedure that executes both queries. example:
delimiter |
create procedure upd_select(IN group INT, IN time INT)
begin
UPDATE table SET time = 0 WHERE group_id = #group and time > #time;
SELECT * FROM table WHERE group_id = #group and time > #time;
end;
|
delimiter ;
So what you're trying to do is reset time to zero whenever you access a row -- sort of like a trigger, but MySQL cannot do triggers after SELECT.
Probably the best way to do it with one server request from the app is to write a stored procedure that updates and then returns the row. If it's very important to have the two occur together, wrap the two statements in a transaction.
There is a faster version of the return of updated rows, and more correct when dealing with highly loaded system asks for the execution of the query at the same time on the same database server
update table_name WITH (UPDLOCK, READPAST)
SET state = 1
OUTPUT inserted.
UPDATE tab SET column=value RETURNING column1,column2...

Get affected row in Ruby after doing an insert in MySQL?

Pretty straight forward problem. I simply want to return the affected row created by a SQL INSERT query so I can get data from it.
There's a way I can do it already, I suppose, but I'm hoping the Mysql or Mysql2 gem provides some mechanism for me not having to make the second SELECT query.
The solution I'm leaning towards right now is something akin to:
"INSERT INTO table (col1) VALUES ('value');"
and then:
"SELECT cid FROM table ORDER BY cid DESC LIMIT 1;"
Since cid is the auto-increment index of the table (it's InnoDB fyi), it will always be the largest cid value in the table until you do another INSERT.
Is there any mechanism in Mysql or Mysql2 to avoid having to make that second SELECT query?
MySQL2 has a last_id method. The documentation for that method is worthless but the implementation looks like this:
static VALUE rb_mysql_client_last_id(VALUE self) {
GET_CLIENT(self);
REQUIRE_OPEN_DB(wrapper);
return ULL2NUM(mysql_insert_id(wrapper->client));
}
And the MySQL mysql_insert_id function does this:
Returns the value generated for an AUTO_INCREMENT column by the previous INSERT or UPDATE statement.
So you can do your INSERT and then get the last ID by calling the last_id method.
And BTW, your current approach:
SELECT cid FROM table ORDER BY cid DESC LIMIT 1;
is not safe if you're in a multiprocess environment, consider this:
You INSERT a row.
Another process INSERTs a row.
You SELECT cid FROM table ORDER BY cid DESC LIMIT 1 and get the ID from (2).
You could SELECT last_insert_id() though, last_insert_id() is session-specific so you don't have to worry about other processes when using it.

MySQL - Select and Update in a single command

I need to select a transactionID from a MySQL table and immediately increment it.
SELECT transid FROM idtable;
UPDATE idtable SET transid=transid +1;
I would like to combine the queries but cannot get the correct syntax.
Using a WHERE clause in your UPDATE will have the same effect.
UPDATE table
SET column = column + 1
WHERE column = value
You could use a sub-query style approach, but I have to wonder if there's any need for the initial SELECT. (Can't you just use a WHERE clause on the UPDATE, perhaps involving a multiple table join if so required.)
Take a look at the MySQL UPDATE query syntax for more information.