`UPDATE ... SET ... LIMIT` in MySQL - mysql

I would like to update a specific range of rows, say starting from 30 and ending at 50. How may I achieve that.
I have tried with:
UPDATE tab
SET col = 'somevalue'
LIMIT 30, 50
but this doesn't work. Is there any way that I can update these rows?
The error that I get is:
Check the manual ... for the right syntax to use near ' 50'

Your statement is not valid MySQL syntax and it doesn't make sense. The problem with the syntax is that offset is not supported for update statements (see here).
The problem with the logic is that you have no order by clause. MySQL doesn't guarantee the order of tables when processing them. So the "first" twenty rows and the "next" twenty" rows make no difference.
Why doesn't this do what you want?
UPDATE tab
SET col = 'somevalue'
LIMIT 20;
If you have a specific column that specifies the ordering, you can use where:
UPDATE tab
SET col = 'somevalue'
wHERE ID >= 30 and ID < 50;

I think with update you can not use limit as it is in select(offset support), you will have to try like this:-
UPDATE tab
SET col = 'somevalue'
where id between 30 and 50;
LIMIT can be used with UPDATE but with the row count only, such as
UPDATE tab
SET col = 'somevalue'
where id > 30
limit 20;
Similar question here.

Related

Why offset. limit returns all rows?

The following SQL query return all rowsa instead from 12 to 18.
SELECT `reviews`.*,
`users`.`username` as `user_username`,
`users`.`slug` as `user_slug`
FROM `reviews`
JOIN `users` ON `users`.`id` = `reviews`.`user_id`
WHERE `reviews`.`product_id` = 2
ORDER BY `reviews`.`created_at` DESC LIMIT 12, 18
As result I have to get 6 rows instead all.
Using the OFF SET in the LIMIT query
The OFF SET value is also most often used together with the LIMIT keyword. The OFF SET value allows us to specify which row to start from retrieving data
Let’s suppose that we want to get a limited number of members starting from the middle of the rows, we can use the LIMIT keyword together with the offset value to achieve that. The script shown below gets data starting the second row and limits the results to 2.
SELECT * FROM `members` LIMIT 1, 2;
Refrence and MySQL docs
In your case to return only 6 rows starting from 12(thirteen row) it should be ORDER BY reviews.created_at DESC LIMIT 12, 6

Duplicate entry '1-1110' for key 'INDEX' while removing element from Index

I have a query to update index if something added in between
update My_Table
set NS_LEFT = NS_LEFT + 10
where NS_THREAD = parentThread and NS_LEFT > oldRight
order by NS_LEFT desc
Its working fine -
Now I if I have to delete something in between then I am using query as below
update My_Table
set NS_LEFT = NS_LEFT - 10
where NS_THREAD = parentThread and NS_LEFT > oldRight
order by NS_LEFT desc
Its is not working and throwing error of duplicate Index -
[Code: 1062, SQL State: 23000] (conn=1517) Duplicate entry '1-1110'
for key 'INDEX'
Index(NS_THREAD,NS_LEFT )
How do solve for delete element
Note
This is my work around for MariaDB only for other other Database its working without OrderBy (Why.. its still open question for me)
What I have done in the past when controlling the order is not an option is to perform two updates. The first shifts the group way up past any currently used values, insuring no collisions. The second then shifts them to where they should be. In general form, the idea can be illustrated with this:
UPDATE aTable SET somevalue = somevalue + 10000 WHERE somevalue > x;
UPDATE aTable SET somevalue = somevalue - 10000 - y WHERE somevalue > x + 10000;
"10000" is just a value that will push the range past collision, y is the amount you actually want to shift them. Obviously if there are already values around 10000, the number will need to be different. To avoid having to query for a safe value, another option if the design permits....
If negative values are not used and the table design allows negative numbers, this is version of the process is a little simpler to apply:
UPDATE aTable SET somevalue = somevalue * -1 WHERE somevalue > x;
UPDATE aTable SET somevalue = (somevalue * -1) - y WHERE somevalue < 0;
This presumes there are not normally negative values, and to be safe the updates should be performed within a transaction (along with the original delete) so that a potential concurrent applications of this solution do not collide. (Edit: Note that transactions/concurrency requirement goes for both forms I have presented.)
Edit: Oh, I just noticed Gordon's answer was quite similar... the bare minus signs looked like flecks on my screen. If Gordon's didn't work, this won't either.
That happens. One solution is to do two updates:
update My_Table
set NS_LEFT = - (NS_LEFT - 10)
where NS_THREAD = parentThread and NS_LEFT > oldRight
order by NS_LEFT desc;
update My_Table
set NS_LEFT = - NS_LEFT
where NS_THREAD = parentThread and NS_LEFT < 0;

UPDATE order in PostgreSQL

I have a mysql command:
update table_demo SET flag= 1 where flag=0 ORDER BY id ASC LIMIT 10
and need the same command in Postgres, I get this error:
ERROR: syntax error at or near 'ORDER'
To update 10 first rows (that actually need the update):
UPDATE table_demo t
SET flag = 1
FROM (
SELECT table_demo_id -- use your actual PK column(s)
FROM table_demo
WHERE flag IS DISTINCT FROM 1
ORDER BY id
LIMIT 10
FOR UPDATE
) u
WHERE u.table_demo_id = t.table_demo_id;
FOR UPDATE (row level locks) are only needed to protect against concurrent write access. If your transaction is the only one writing to that table, you don't need it.
If flag is defined NOT NULL, you can use WHERE flag <> 0.
Related answers with more explanation and links:
Update top N values using PostgreSQL
How do I (or can I) SELECT DISTINCT on multiple columns?

Update first row in SQL using LIMIT

I'm having a trouble with something that looks like simple thing. I'm trying to find first row that satisfies WHERE part of query and UPDATE it.
UPDATE Donation SET Available=0 WHERE Available != 0 and BloodGroup='" + bloodGroup + "' LIMIT 1"
bloodGroup is variable that gets filled automatically using C# and it keeps string value of selected blood group.
When I try to run this I get incorrect syntax near 'limit'.
What I'm doing wrong? Is it possible using LIMIT like during UPDATE query?
During debugging I got query like this:
UPDATE Donation SET Available=0 WHERE Available != 0 AND BloodGroup='AB-' LIMIT 1
Because C# is often used with SQL Server, perhaps the question is mistagged. The syntax looks fine for MySQL.
In SQL Server, you can do this as:
UPDATE TOP (1) Donation
SET Available = 0
WHERE Available <> 0 AND BloodGroup = 'AB-';
Note that this chooses an arbitrary matching row, as does your original query (there is no order by).
It is not safe to use limit in update queries.
Please refer
http://bugs.mysql.com/bug.php?id=42415
The documentation states that any UPDATE statement with LIMIT clause is considered unsafe since the order of the rows affected is not defined: http://dev.mysql.com/doc/refman/5.1/en/replication-features-limit.html
However, if "ORDER BY PK" is used, the order of rows is defined and such a statement could be logged in statement format without any warning.
You can use like this way limit in Update Queries like these
UPDATE messages SET test_read=1
WHERE id IN (
SELECT id FROM (
SELECT id FROM messages
ORDER BY date_added DESC
LIMIT 5, 5
) tmp
);
Also please
Can you try it? way of getting row_number
UPDATE Donation d1 join (SELECT id,(SELECT #Row:=0) as row,(#Row := #Row + 1) AS row_number FROM Donation where Available <> 0 AND BloodGroup='AB-') d2
ON d1.id=d2.id
SET d1.Available='three'
WHERE d1.Available <> 0 AND d1.BloodGroup='AB-' AND d2.row_number='1'

limiting number of elements in a result set

I'm trying to limit the number of elements in my result set by setting a limit to my sql logic. I have two seperate functions to achieve what I want. The first one has a limit I've set manually e.g 0, X. The second function has two extra arguments that is min and max and these are set as the limit. But when the min and max are e.g 7, 14 it gives me more elements then 7. There are no duplications in the result set since I have unique id's on each element and they check out. Also the integers passed to the sql function have the correct intervall.
What am I doing wrong?
"SELECT table1.*, table2.user_id FROM table1 LEFT JOIN table2 ON table1.col1 = table2.col2
WHERE table1.col1 = :param1 AND table1.col2 = 1 AND table1.col3 = 0 ORDER BY table1.col4 DESC LIMIT $min, $max";
The syntax is SELECT Syntax is not
limit min, max
but
limit offset, row_count
so, limit 7, 14 says retrieve 14 rows at offset 7.