Update order by limit is giving me an error - mysql

I want to update a table using order by and limit. The reason is that I want to offset the first 3 entries. I started by making a query to list what I wanted to update, and that works.
SELECT `Name`,`active`
FROM `tlogon`
WHERE `active`>0 ORDER BY `id` LIMIT 3,18446744073709551610
So I have 8 items in my table and it is showing the last 3 which is correct, because 2 of the rows have an active of zero. So then I tried to turn my select into an update like this.
UPDATE `tlogon` SET `active`=3
WHERE `active`>0 ORDER BY `id` LIMIT 3,18446744073709551610
The idea here is that it gets a list of active and ignores the first 3, and then I only want to update after the first three. However the above code gives an error in phpmyadmin.
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '18446744073709551610' at line 2
So my question is. Why does my select work, but my update query fail?
EDIT
Ok I have tried something else, but again I have failed. My id is autoincrementing so I tried the following code
UPDATE `tlogon` SET `active`=3
Where `id`>=(
SELECT `id`
FROM `tlogon`
WHERE `active`>0 ORDER BY `id` LIMIT 3,1
)
Now it works in simulation, but the problem when I do it for real I get this error.
#1093 - You can't specify target table 'tlogon' for update in FROM clause
Which is annoying because what I am doing is getting the first id above my limit and changing them, but again I have failed.
So then I thought about a Right Join like this
UPDATE `tlogon` AS `a`
RIGHT JOIN `tlogon` AS `b` ON `a`.`id`>`b`.`id`
SET `a`.`active`=3
WHERE (
SELECT `id`
FROM `b`
WHERE `tlogon`.`active`>0 ORDER BY `tlogon`.`id` LIMIT 3,1
)
But I think I am doing something wrong because now it is telling me that table b does not exist.

The UPDATE statement does not support an offset for LIMIT, only the number of rows to update.
Its syntax is:
UPDATE [LOW_PRIORITY] [IGNORE] table_reference
SET col_name={expr | DEFAULT},
[, col_name={expr | DEFAULT}] ...
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
You need to find another way to ignore the first 3 rows.

Ok I have an answer, but it only works if you are using an auto incrementing id.
UPDATE `tlogon` AS `a`
INNER JOIN
(SELECT `id`
FROM `tlogon`
WHERE `active`>0 ORDER BY `id` LIMIT 3,1) as b ON `a`.`id` >= `b`.`id`
SET `a`.`active`=3
because you cannot reference the same table with the select I ended up using an inner join to the same table.
Basically I am getting the next highest id in my where clause and only changing active if the id is higher. Thus the first 3 entries will be ignored and the rest will be changed to 3, which is what I wanted.

Related

Delete duplicates for multiple columns in JOIN on same table

I am trying to make a delete from joined same table like this:
DELETE FROM `sp10_seo_url` AS sp1 JOIN
(
SELECT seo_url_pk, COUNT(*) AS maxc
FROM `sp10_seo_url`
GROUP BY seo_url_entity_type, seo_url_entity_id, seo_url_language_fk
HAVING maxc > 1
) AS sp2
ON sp1.seo_url_pk = sp2.seo_url_pk
However I am getting a mysql error
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS sp1 JOIN ( SELECT seo_url_pk, COUNT(*) AS maxc FROM `sp10_s' at line 1
And I am not sure at all where the error is. The inner query runs just fine and returns the expected set of results. The "ON" keys are properly named (same since we are talking about the same table).
I guess the idea of the query is pretty clear (clean the table of different rows have the same set of values for the three "group by" columns. Is there another way to do this?
Thanks!
you can "cheat" mysql with a double indirection (as explained here Deleting a row based on the max value):
delete from `sp10_seo_url`
where seo_url_pk in (
select seo_url_pk from (
SELECT seo_url_pk
FROM `sp10_seo_url` sp1,
(
SELECT seo_url_entity_type, seo_url_entity_id, seo_url_language_fk
FROM `sp10_seo_url`
GROUP BY seo_url_entity_type, seo_url_entity_id, seo_url_language_fk
HAVING count(*) > 1
) sp2
where sp1.seo_url_entity_type = sp2.seo_url_entity_type
and sp1.seo_url_entity_id = sp2.seo_url_entity_id
and sp1.seo_url_language_fk = sp2.seo_url_language_fk
) t
);
http://sqlfiddle.com/#!2/899ff5/1

Delete mysql with join and limit

I have such sql-query:
DELETE `LINK_LA_TYP`
FROM
`LINK_LA_TYP`
JOIN `LINK_ART` ON `LINK_LA_TYP`.LAT_LA_ID = `LINK_ART`.LA_ID
JOIN `ARTICLES` ON `LINK_ART`.LA_ART_ID = `ARTICLES`.ART_ID
WHERE
(
`ARTICLES`.ART_SUP_ID IN(
10008,
10439,
11005,
...
...
441
)
)
LIMIT 50000;
But i get error.... From mysql-doc i get that with delete+join+limit i will get errors....
But how can i change my code? (new to mysql and sql in all). How to change my code? To limit rows to delete....
Also in phpmyadmin i get
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use
near 'limit 50' at line 1
From the docs For the multiple-table syntax, DELETE deletes from each tbl_name the rows that satisfy the conditions. In this case, ORDER BY and LIMIT cannot be used. dev.mysql.com/doc/refman/5.0/en/delete.html – Michael Berkowski 2 mins ago
I concur with this. Additionally,
The DELETE command cannot have a LIMIT clause. Also, generally speaking you cannot DELETE from multiple JOINed tables.
It MIGHT be possible to rewrite the statement using a subselect something like:
delete from LINK_LA_TYP
where LAT_LA_ID in
(select LA_ID
from LINK_ART
join ARTICLES on ARTICLES.ART_ID = LINK_ART.LA_ART_ID
where ARTICLES.ART_SUP_ID in (...));

Updating last but one record -- can not find syntax error in mysql query

I need this query - update last but one record.
UPDATE changes SET checked='' WHERE item_id = 119898 AND type = 'example_edit' AND checked != 'restored' ORDER BY id DESC LIMIT 1, 1
Database echos:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' 1' at line 1
What is wrong near 1?
Standard update staement
UPDATE [LOW_PRIORITY] [IGNORE] table_reference
SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
for your case try this
UPDATE changes SET checked='' WHERE item_id = 119898 AND type = 'example_edit' AND checked != 'restored' ORDER BY id DESC LIMIT 1
Try it will really help you, code tested.
Limit in update can only use row counting not 1,1 etc.
LIMIT can be used with UPDATE but with the row count only. Refer this.
The LIMIT clause places a limit on the number of rows that can be updated.
So this query should work-
UPDATE
changes
SET
checked = ''
WHERE item_id = 119898
AND TYPE = 'example_edit'
AND checked != 'restored'
ORDER BY id DESC
LIMIT 1;

MySQL LIMIT on DELETE statement

I put together a test table for a error I recently came across. It involves the use of LIMIT when attempting to delete a single record from a MySQL table.
The error I speak of is "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LIMIT 1' at line 1"
The table I put together is called test; it has 3 columns, id, name and created. I populated the table with several records and then attempted to delete one. Below is the statement I used to try and accomplish this.
DELETE t FROM test t WHERE t.name = 'foo' LIMIT 1
Without the use of LIMIT 1, the statement executes just fine, but of course I wouldn't be using LIMIT if there wasn't a need for it.
I'm fully aware that I can use another statement to accomplish this DELETE successfully. See below:
DELETE FROM test WHERE name = 'foo' LIMIT 1
However my question is centered on why the first statement isn't working with LIMIT.
So my question is, what I have done incorrectly with respect to the first statement to generate this error?
simply use
DELETE FROM test WHERE 1= 1 LIMIT 10
the delete query only allows for modifiers after the DELETE 'command' to tell the database what/how do handle things.
see this page
From the documentation:
You cannot use ORDER BY or LIMIT in a multiple-table DELETE.
DELETE t.* FROM test t WHERE t.name = 'foo' LIMIT 1
#Andre If I understood what you are asking, I think the only thing missing is the t.* before FROM.
Use row_count - your_desired_offset
So if we had 10 rows and want to offset 3
10 - 3 = 7
Now the query delete from table where this = that order asc limit 7 keeps the last 3, and order desc to keep the first 3:
$row_count - $offset = $limit
Delete from table where entry = criteria order by ts asc limit $limit
There is a workaround to solve this problem by using a derived table.
DELETE t1 FROM test t1 JOIN (SELECT t.id FROM test LIMIT 1) t2 ON t1.id = t2.id
Because the LIMIT is inside the derived table the join will match only 1 row and thus the query will delete only this row.
First I struggled a bit with a
DELETE FROM ... USING ... WHERE query,...
Since i wanted to test first
so i tried with SELECT FROM ... USING... WHERE ...
and this caused an error , ...
Then i wanted to reduce the number of deletions adding
LIMIT 10
which also produced an error
Then i removed the "LIMIT" and - hurray - it worked:
"1867 rows deleted. (Query took 1.3025 seconds.)"
The query was:
DELETE FROM tableX
USING tableX , tableX as Dup
WHERE NOT tableX .id = Dup.id
AND tableX .id > Dup.id
AND tableX .email= Dup.email
AND tableX .mobil = Dup.mobil
This worked.

mysql - UPDATE with LIMIT x, y

UPDATE table SET checked = 1 WHERE field = 'xxx' LIMIT 1
works fine, but
UPDATE table SET checked = 1 WHERE field = 'xxx' LIMIT 1, 10
throw error "#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' 10' at line 1"
Why it is not possible? I want to update everything except first row.
update table set checked = 1 where id in (select * from (select id from table where field = 'xxx' order by id limit 1, 10) as t)
LIMIT in an UPDATE clause is merely an upper limit on how many rows may be updated.
It's not like in a SELECT where you can ignore all but a certain subrange of result rows to deal with.
If you really need something like this, you should use a VIEW with the LIMIT restriction, and perform the UPDATE on that.
I had a similar situation, but in my case I needed to update only 2 rows ordered by a numerical ID, so my query would've been like this:
UPDATE myTable
SET Column1='some data',Column2='some othe data'
WHERE Column3='some criteria' LIMIT 1;
UPDATE myTable
SET Column1='some data',Col2='some othe data'
WHERE Column3='some criteria2' ORDER BY ID DESC LIMIT 1;
Note: The first query implicitly selects the first matching row in the table, and the second query selects the second matching row by explicitly reversing the order. It doesn't answer the question but it may benefit someone with problem similar to mine.