Delete subquery with alias MySQL - mysql

I have a problem with this delete query:
DELETE r
FROM table AS r
WHERE r.stoptime IS NULL
and r.address IN
(select address from table where starttime <= r.starttime and stoptime > r.starttime)
I get the following error:
Error : You can't specify target table 'r' for update in FROM clause.
My goal is to delete records that the starttime is contained in another record but I got an error with the alias in the subquery.
Somebody know how to do this? Thanks in advance.

Try to use JOINS like this:
DELETE r
FROM `table` r
JOIN `table` t ON t.id = r.id
WHERE t.starttime <= r.starttime and t.stoptime > r.starttime
AND r.stoptime IS NULL

Related

Update table row with values from same table column row

I want to update the values of column created_at with values of column updated_at, where value in the column created_at is 0000-00-00.
I tried the following query :
UPDATE tbl_message_types a
SET a.created_at = (
SELECT
c.updated_at
FROM
( SELECT b.updated_at
FROM tbl_message_types b
WHERE b.created_at LIKE '%0000-00-00%'
AND a.id = c.id ) AS c
)
AND a.created_at LIKE '%0000-00-00%';
But the result of the query is as follows :
> 1054 - Unknown column 'a.id' in 'where clause'
> Time: 0.008s
How can I modify the query ?
Your alias is out of place, but I would phrase this update using a join:
UPDATE tbl_message_types a
INNER JOIN UPDATE tbl_message_types b
ON a.id = b.id AND
COALESCE(b.created_at, '0000-00-00') != '0000-00-00'
WHERE COALESCE(a.created_at, '0000-00-00') = '0000-00-00';
Note that it is not clear how you ended up with datetime values of 0000-00-00 in your table. I am treating NULL the same way in my answer, though you may remove the call to COALESCE if you disagree.
I think you can do it in much simplified way.. without any join gimmicks; Why should you insist on a single query..? Do the select First, and update next. Try this..
select
value1 from tableName
where columnX like '%someThing%' and columnY = 'SomeValue' as value11;
update sametableName set someColumn= value11
where....

MySQL JOIN Statement with Two Conditions

I have two tables both with columns called member_id. I'd like to select all member_ids...
WHERE end_date <= NOW() from table 1, and
approved='n' from table 2.
I'm very unfamiliar with JOIN, but I believe this is what's needed here. Something like this doesn't seem to be working though...
SELECT both.member_id, both.course_id
FROM vbc_status
INNER JOIN course_enrollment ON both.member_id=both.member_id AND
both.end_date <= NOW() AND
both.approved='n'
How can I make this happen?
You still have to reference the original columns by their source even after the join. I'm not sure which table has course_id so you'll have to fix that one before it will run.
SELECT vbc_status.member_id, ?.course_id
FROM vbc_status INNER JOIN course_enrollment
ON vbc_status.member_id = course_enrollment.member_id
AND vbc_status.end_date <= NOW() AND course_enrollment.approved = 'n'
You'd probably find table aliases to be handy.
I think you want this:
SELECT *
FROM vbc_status v
INNER JOIN course_enrollment c ON v.member_id = c.member_id
WHERE v.end_date <= NOW() AND c.approved='n'
SELECT t1.member_id, t1.course_id FROM vbc_status t1
JOIN course_enrollment ce USING(member_id)
WHERE t1.end_date <= NOW() AND ce.approved='n'
I assumed end_date is a column of vbc_status and approved is a column of course_enrollment.
Explanation of the statement:
You set up table aliases with vbc_status t1, this makes t1 the alias for the table vbc_status, and course_enrollment gets the alias ce.
Then on selecting you have to prefix the fields you want to see with the alias of the table, and the same goes for the where statement.

Deleting duplicates from a table with a single SQL command using this statement that selects them

Please help me with the SQL that can transform this select command that finds the duplicates in this table into SQL that will delete all by one of the duplicates.
NOTE - There is a primary key: "event_id" that I can use the MIN statement to select the surviving instance to keep. However, I have not been successful writing the SQL.
Thanks!
Here is the SELECT to find the duplicates:
SELECT airport_id, DATE( event_from ) , count( * )
FROM tbl_events
WHERE airport_id NOT LIKE ""
AND DATE( event_from ) > "2014-08-11"
GROUP BY airport_id, DATE( event_from )
HAVING count( * ) >1
You can do this using delete with a join. The only modification to your query is to add in the id that is being kept and some column aliases. The rest is just joining it to the original table for the delete:
delete e
from tbl_events e join
(SELECT airport_id, DATE(event_from) as date,
count(*) as cnt, MIN(event_id) as min_event_id
FROM tbl_events
WHERE airport_id NOT LIKE '' AND DATE( event_from ) > '2014-08-11'
GROUP BY airport_id, DATE( event_from )
HAVING count(*) > 1
) dups
on e.airport_id = dups.airport_id and
date(e.event_from) = dups.date and
e.event_id > dups.min_event_id;
As a general rule, you should use single quotes (instead of double quotes) for string and date constants. This is the standard that is supported by just about all databases.
Use the "delete with join" syntax:
DELETE t FROM tbl_events t
JOIN tbl_events t2 ON t.id < t2.id
AND t.airport_id = t2.airport_id
AND DATE(t.event_from) = DATE(t2.event_from)
WHERE t.airport_id NOT LIKE ''
AND DATE(t.event_from) > '2014-08-11'
The key to deleting of one of the duplicates is the join condition t.id < t2.id, which separates ties by both stopping rows from joining to themselves and causing all but highest-numbered id of all of the duplicate from being deleted.
Note that this assumes there is a id column that is unique. If id doesn't exist, use any column that is unique instead.

Intermediate MySQL query: updating table column based on separate table column value

I have a table ticketdetails which contains a column with data that I want to copy to another table's column:
SELECT TicketID, MIN( StartTime ) StartTime
FROM ticketdetails
GROUP BY TicketID #might be unnecessary?
ORDER BY TicketID
The output looks like this:
I want the result of this query, "StartTime", to be supplied in my other table column, tickets.TimeScheduled, where the TicketID matches for both tables.
Right now I'm trying:
UPDATE tickets SET TimeScheduled = (
SELECT MIN( StartTime ) StartTime
FROM ticketdetails
GROUP BY TicketID
ORDER BY TicketID)
WHERE tickets.TicketID = ticketdetails.TicketID
I get this error:
#1054 - Unknown column 'ticketdetails.TicketID' in 'where clause'
I know that this column exists in my database. For some reason the query doesn't recognize the column. I think I need a JOIN or something, but I'm not the best with intermediate-advanced MySQL queries. Help is much appreciated.
Use a join:
UPDATE tickets AS t
JOIN (SELECT TicketID, MIN( StartTime ) StartTime
FROM ticketdetails
GROUP BY TicketID) AS d ON t.TicketID = d.TicketID
SET t.TimeScheduled = d.StartTime
The reason you're getting an Unknown column error is because the ticketdetails table only exists in the subquery, not in the main query.
If you want to set timeScheduled to NULL if there's no matching ticket in ticketdetails, change JOIN to LEFT JOIN.
BTW, there's no need for ORDER BY in the subquery.
You can do this with a correlated subquery:
UPDATE tickets
SET TimeScheduled = (SELECT MIN( td.StartTime ) StartTime
FROM ticketdetails td
WHERE td.TicketID = t.TicketID
);

Can't delete all records except first one

I'm trying to delete all records from a certain user except the first one, however I'm getting this error:
1093 - You can't specify target table 'History' for update in FROM clause
I don't understand what's the problem and also I found a similar question in SO that proposed this same solution. This is my query:
DELETE FROM `History` WHERE ID = '3' AND Date NOT IN (SELECT min(Date) FROM `History` WHERE ID = '3')
Try converting it to JOIN
DELETE a
FROM History a
LEFT JOIN History b
ON a.Date = b.Date AND
b.ID = 3
WHERE b.date IS NULL AND
a.ID = 3
Before executing the statement above, please do backup the table first.
Here is another way to solve this problem, by wrapping the subquery in another layer of a subquery. MySQL generates the intermediate query, which prevents this error:
DELETE FROM `History`
WHERE ID = '3' AND
Date NOT IN (select mindate
from (SELECT min(Date) as mindate FROM `History` WHERE ID = '3')
)
Please try the below query once
DELETE FROM `History` main WHERE main.ID = '3'
AND main.Date NOT IN
(SELECT min(inn.Date) FROM `History` WHERE main.ID = inn.id)