Reputation: 355
I have the following mySQL Query which returns a list of ID's. I want to delete the rows with each ID of the list from the table "serverking_user"
SELECT serverking_user.id FROM (serverking_user
INNER JOIN serverking_logins
ON serverking_user.id=serverking_logins.uid)
WHERE serverking_logins.time < 3600
GROUP BY serverking_user.id
HAVING COUNT(serverking_logins.login) = 1
One possibility would be to loop through each ID by using "in". But since "in" is deactivated on my Sql Server I need to solve this with a "join".
Any ideas ?
Upvotes: 0
Views: 425
Reputation: 19635
It has been a while since I have done MySQL development, but if I remember correctly this should work for you:
DELETE su
FROM serverking_user su
INNER JOIN serverking_logins sl
ON su.id=sl.uid
WHERE sl.time < 3600
GROUP BY su.id
HAVING COUNT(sl.login) = 1
In general, if you want to delete records from a single table in a JOIN, you just specify that table (or its alias) after DELETE
UPDATED QUERY
It seems that MySQL isn't fond of deleting where a grouped query is involved, so another possibility is to use an anti-join. However, I'm sure that the performance characteristics of this query will be suboptimal. It may be better to use two separate queries instead. Nonetheless, here is a solution using anti-joins:
DELETE su
FROM serverking_user su
INNER JOIN serverking_logins sl
ON su.id=sl.uid
LEFT JOIN serverking_logins antisl
ON sl.uid = antisl.uid
AND sl.id <> antisl.id
WHERE sl.time < 3600
AND antisl.id IS NULL
Upvotes: 2
Reputation: 873
DELETE FROM serverking_user
WHERE EXISTS
(SELECT *
FROM (serverking_user
INNER JOIN serverking_logins
ON serverking_user.id=serverking_logins.uid)
WHERE serverking_logins.time < 3600
GROUP BY serverking_user.id
HAVING COUNT(serverking_logins.login) = 1) a
Upvotes: 1
Reputation: 63772
Perhaps you could store the results of the select inside of a table variable and then join that?
declare @Ids table
(
Id int
);
insert into @Ids (Id)
SELECT serverking_user.id FROM (serverking_user
INNER JOIN serverking_logins
ON serverking_user.id=serverking_logins.uid)
WHERE serverking_logins.time < 3600
GROUP BY serverking_user.id
HAVING COUNT(serverking_logins.login) = 1;
delete yt from YourTable yt
inner join @Ids Ids on Ids.Id = yt.id;
Note that the consistency of this depends on your transaction configuration, since you're doing two separate queries here.
Upvotes: 1