MySQL DELETE with JOIN getting syntax error with LIMIT statement - mysql

I am running a query to remove duplicate entries. It works without the LIMIT statement, but overloads the server. I'd like to batch process it using the LIMIT statement.
DELETE t1
FROM data as t1
join data as t2
WHERE t1.type = t2.type
AND t1.timestamp = t2.timestamp
LIMIT 100
And with the LIMIT statement receive the error:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'LIMIT 100' at line 6

you can't use direcly the limit in delete you could use in select
DELETE data
FROM data as t1
join (
select distinct type, timestamp from data limit 100
) t2 on t1.type = t2.type AND t1.timestamp = t2.timestamp

Multi-table DELETE and UPDATE do not permit a LIMIT clause. This is the cause of the error message. To workaround...
To do massive DELETEs (or UPDATEs), loop through the table in chunks. This discusses the details. For efficiency, it uses the PRIMARY KEY so that walking through the table is efficient.

Related

cant't run the follorwing Query Clause query shows an error message in goormide

Running a query that has similar syntax:
WITH table1
AS
(SELECT
COUNT(*)
FROM photos
),
table2 AS (
SELECT
COUNT(*)
FROM
users
)
SELECT table1 / table2;
I'm getting the following error, but not sure why? Really new to SQL. Thanks !
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 'table1 AS
You can't use the CTE syntax because you are using MySQL Server 5.7. CTE is a new feature introduced in MySQL 8.0.
But you don't need it for the query you show. You can do it this way:
SELECT table1.count / table2.count
FROM (SELECT COUNT(*) AS count FROM photos) AS table1
CROSS JOIN (SELECT COUNT(*) AS count FROM users) AS table2;

Subquery to find the 3rd highest cost of the products sold

i have been trying to find the 3rd highest cost of the product sold.
from table tblproducts.i am using mysql server 5.6.
i used the below query:
select name
from tblproducts
where cost IN
(select distinct top 3 cost
from tblproducts
order by cost desc);
but when i run the query it shows the below error:
ERROR 1064 (42000): 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 '3 cos
t
from tbbproducts
order by cost dec)' at line 4
.....................
someone kindly help me with the syntax to correct this error.
thankyou.
SELECT t1.name
FROM tblproducts t1
WHERE (3) = ( SELECT COUNT(t2.cost)
FROM tblproducts t2
WHERE t2.cost >= t1.cost
)
Demo here:
SQLFiddle
Update:
The above query works fine so long as there is no possibility for products with duplicate costs in tblproducts. If there be the chance for cost duplicates, then we can modify the query as follows:
SELECT t1.name
FROM tblproducts t1
WHERE (3) = ( SELECT COUNT(t2.cost)
FROM (SELECT DISTINCT cost FROM tblproducts) t2
WHERE t2.cost >= t1.cost
)

Delete MySQL row using where clause

I'm trying to delete duplicate rows according to some fileds.
When I'm running the query below:
delete
from slowmo_vid as sv1, slowmo_vid as sv2
where sv1.video_id = '2luh6g3ni5ex'
and sv1.slowmo_end_t<=sv2.slowmo_end_t;
I'm getting the 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 sv1, slowmo_vid as sv2
where sv1.video_id = '2luh6g3ni5ex'
and sv1.slowmo_end' at line 2
The fields of the tables are : id, video_id internal_uri, slowmo_end_t
You seem to be trying to do an ANSI-92 style inner join inside a DELETE statement. But the WHERE clause cannot simultaneously be used to enforce the join and enforce a restriction on a result set. Instead, do the following explicit INNER JOIN to remove the records you want. Notice that it is clear what role the WHERE clause is playing.
Update: If you want to delete all records except for the one containing the max video_id then you can add a nested subquery to the WHERE clause.
DELETE sv1.*
FROM slowmo_vid sv1
INNER JOIN slowmo_vid sv2 ON sv1.slowmo_end_t <= sv2.slowmo_end_t
WHERE sv1.video_id = '2luh6g3ni5ex' AND
sv1.video_id <> (SELECT x.id
FROM (SELECT MAX(t.video_id) AS id
FROM slowmo_vid t) x)
You can specify multiple tables in a DELETE statement to delete rows
from one or more tables depending on the particular condition in the
WHERE clause. However, you cannot use ORDER BY or LIMIT in a
multiple-table DELETE. The table_references clause lists the tables
involved in the join. Its syntax is described in Section 12.2.8.1,
“JOIN Syntax”.
http://dev.mysql.com/doc/refman/5.6/en/delete.html
The example in the manual is:
DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3
WHERE t1.id=t2.id AND t2.id=t3.id;
You cannot use aliases on DELETE statement. You can try with:
DELETE FROM myAlias USING `my_table` AS myAlias
Or try without any aliases

How Can i write update statement in mysql with select query?

I want to update table1 by taking max(date) and min(Date) from Table2 for only if table1.status=100 and table1.Todate='0000-00-00 00:00:00'
same thing I am trying with following query but it is giving error in group by
update table1 s
left join table2 t
on s.stCode=t.tsTask
set s.stActFrom= min(t.tsDate),s.stActTo=max(t.tsDate)
WHERE s.stActTo='0000-00-00 00:00:00' and s.stStatus=100
group by t.`tsTask`
if i execute this query i am getting following 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 'group by t.tsTask' at line 1
Can any one tell me how i can write this update query?
update s
set s.stActFrom= t.MinDate,
s.stActTo = t.MaxDate
FROM table1 s left join
(
SELECT MinDate = min(tsDate), MaxDate = max(tsDate)
FROM table2
group by `tsTask`
) AS t
WHERE s.stActTo='0000-00-00 00:00:00' and s.stStatus=100
ON s.stCode=t.tsTask
I have tried the above answers. That is not given me the required answer. So i have got answer from the following query.
update table1 s left join
(
SELECT min( tsDate ) AS MinDates, max( tsDate ) AS MaxDates, tsTask
FROM table2
group by `tsTask`
) AS t ON s.stCode=t.tsTask
set s.stActFrom= t.MinDate,
s.stActTo = t.MaxDate
WHERE s.stActTo='0000-00-00 00:00:00' and s.stStatus=100

Delete with join on the same table and limit clause

I have a MySql table like this,
Session_Id Subscriber_Id Status
-------------------------------
abc 1234 Started
bcd 1235 Started
bcd 1235 Finished
And I need to delete rows with status 'Started' only if followed by a 'Finished'. This is a huge table, so I would be deleting 1000 records at a time.
I read up a few similar threads,
Multiple-table DELETE LIMIT,
DELETE FROM `table` AS `alias` ... WHERE `alias`.`column` ... why syntax error?
and tried the below queries,
mysql> delete a.* from FSESSION as a, FSESSION as b where a.status='Started' and b.status='Finished' and a.session_id=b.session_id limit 1000;
ERROR 1064 (42000): 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 1000' at line 1 ----> If I remove 'limit' this works
mysql> DELETE FROM v USING `FSESSION` AS v WHERE status = 'Started' and exists(select 0 from FSESSION t where t.status='Finished' and v.session_id=t.session_id) limit 1000;
ERROR 1064 (42000): 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 1000' at line 1 ---->
Does'nt work even when limit is removed.
I use MySql version 5.1.56-ndb-7.1.15. Please suggest a way to do this. Thanks!
UPDATED based on your comments
DELETE f
FROM fsession f JOIN
(
SELECT session_id, subscriber_id
FROM fsession
WHERE status IN('Started', 'Finished')
GROUP BY Session_Id, Subscriber_Id
HAVING MAX(status = 'Started') > 0
AND MAX(status = 'Finished') > 0
LIMIT 1000 -- limit here means how many pairs of rows, so it's effectively 2x rows
) q ON f.session_id = q.session_id
AND f.subscriber_id = q.subscriber_id
To know how many rows were deleted use ROW_COUNT()
SELECT ROW_COUNT();
Here is SQLFiddle demo
Try these queries:
CREATE TEMPORARY TABLE FSESSION_TEMP
(
Temp_Session_Id varchar(255)
);
INSERT INTO FSESSION_TEMP
(
SELECT a.Session_Id FROM
FSESSION a,
FSESSION b
WHERE
a.Status = 'Started' and
b.Status = 'Finished' and
a.Session_ID = b.Session_ID
LIMIT 2
);
DELETE FROM
FSESSION
WHERE
Session_ID in (SELECT * FROM FSESSION_TEMP)
;
DROP TABLE FSESSION_TEMP;
Here is the SQL Fiddle. I've set LIMIT at 2 to show that it works. You still need to change it to 1000.
It seems that you need to use a temporary table for this for 2 reasons:
1) MySQL doesn't let you delete from a table when you use the same table in a subquery
2) 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 (Taken straight out of the MYSQL DELETE manual)
There is one way to circumvent the restrictions by using the DELETE syntax with JOIN and joining the original table (where rows will be deleted from) with a derived table (identical to the above temporary one):
DELETE fdel
FROM
FSESSION fdel
JOIN
(
SELECT a.Session_Id
FROM
FSESSION a
JOIN
FSESSION b
ON a.Session_ID = b.Session_ID
WHERE
a.Status = 'Started' and
b.Status = 'Finished'
LIMIT 2
) ftemp
ON ftemp.Session_ID = fdel.Session_ID
;