Delete from subquery - mysql

I am using Hibernate in my application. Currently I am trying to execute the following query:
DELETE FROM ActiveTimes a WHERE
a.begin>=:from AND a.begin<=:to
AND a.end>=:from AND a.end<=:to
AND a in(
SELECT al FROM ActiveTimes al
JOIN al.source.stage st
JOIN st.level.dataSource ds
WHERE ds=:dataSource)
But I get an error: Column 'id' in field list is ambiguous.
This feels normal, because the created SQL query looks like this:
delete
from
active_times
where
begin>=?
and begin<=?
and end>=?
and end<=?
and (
id in (
select
id
from
active_times activeti1_
inner join
sources sourc2_
on activeti1_.source=sourc2_.id
inner join
stage stage3_
on sourc2_.id=stage3_.source
inner join
levels levels4_
on stage3_.level=levels4_.id
inner join
datasources datasource5_
on levels4_.data_source=datasource5_.id
where
id=?
)
)
If I change the query to:
DELETE FROM ActiveTimes a WHERE
a.begin>=:from AND a.begin<=:to
AND a.end>=:from AND a.end<=:to
AND a.id in(
SELECT al.id FROM ActiveTimes al
JOIN al.source.stage st
JOIN st.level.dataSource ds
WHERE ds.id=:dataSource)
I get another error: You can't specify target table 'active_times' for update in FROM clause.
I am not very experimented with JPQL(or HQL) so I do not understand why the query looks like that in the first example.
The new error occurs because apparently I cannot make a subquery on the delete table in MySQL.
Do you have any suggestions on how can I rewrite one of the above queries in order to make it work?

Just remove the sub-query. It's unnecessary. I'm not sure how to write SQL code in Hybernate, but I'm guessing it would be something like this:
DELETE a
FROM ActiveTimes a
JOIN a.source.stage st
JOIN st.level.dataSource ds
WHERE a.begin>=:from AND a.begin<=:to
AND a.end>=:from AND a.end<=:to
AND ds.id=:dataSource;

Related

SQL Delete Erro #1064

I don't know why this my DELETE sql command got the error number #1064.
My delete sql:
delete from nit.grades g where
(select id_dep from nit.offers as oo,nit.subjects as s where s.id=oo.id_subject and g.id_offer=oo.id)
!=(select id_dep from nit.students as stu where g.id_student=stu.id);
but this sql Select same where clause is working.
select * from nit.grades g where
(select id_dep from nit.offers as oo,nit.subjects as s where s.id=oo.id_subject and g.id_offer=oo.id)
!=(select id_dep from nit.students as stu where g.id_student=stu.id);
thanks for any help.
the Error message:
The syntax with the alias of the table you use for the delete statement is wrong.
Even more in the subqueries you use the target table and this is not allowed in MySql.
Instead you should use joins.
From your code this is what I understood that you want:
delete g
from nit.grades g
inner join nit.offers oo on g.id_offer = oo.id
inner join nit.subjects s on s.id = oo.id_subject
inner join nit.students st on g.id_student = st.id
where st.id_dep <> s.id_dep
In the WHERE clause I'm not sure if the columns id_dep are qualified correctly because they are not qualified also in your code.
If this is not what you want to do then use your SELECT query which does work (as you say) as a join to the table, provided there is a primary key like id in nit.grades:
delete g
from nit.grades g
inner join (
<your select query here>
) t
on t.id = g.id

Get sequel generated sql to generate field names without backticks

I have the following query written in SQL:
Select *
From npt_articles
Inner Join npt_authors
Inner Join users
Inner Join npt_teams
Where npt_teams.id In (1)
and the following sql generated by the sequel gem:
SELECT *
FROM `npt_articles`
INNER JOIN `npt_authors`
INNER JOIN `users`
INNER JOIN `npt_teams`
WHERE ('npt_teams.id' IN (1))
The first returns results, the second one doesn't, if I remove the back-ticks then the second then it generates the same result as the first.
This is the code that generates the second sql:
team_articles = user.npt_teams.to_a.inject({}) {|arts,team|
arts.merge({ team.name =>
NptArticle.join(:npt_authors).join(:users).join(:npt_teams).where('npt_teams.id' => [team.id]).to_a.uniq})
}
How do I get the query generated without backticks?
You should try something like this:
.where(:npt_teams__id => [team.id])

MySQL Delete: two similar codes, only one works

I have two similar SQL queries to solve a problem, though only the second one works.
The problem is:
Considering only muscular disorders, write a query to delete the onsets, which ended up with recovery, of patients that contracted and cured at least two (muscular) diseases.
The database has this structure:
Onset (Patient,Pathology,OnsetDate,RecoveryDate)
Pathology (Name,BodyPart)
This is my first code:
DELETE ES.*
FROM Onset ES NATURAL JOIN
(
SELECT E.Patient, E.Pathology, E.OnsetDate
FROM Onset E INNER JOIN Pathology P ON E.Pathology=P.Name
WHERE P.BodyPart='Muscles'
AND E.RecoveryDate IS NOT NULL
AND 2<=(SELECT COUNT(DISTINCT E2.Pathology)
FROM Onset E2 INNER JOIN Pathology P2 ON E2.Pathology=P2.Name
WHERE P2.BodyPart='Muscles'
AND E2.Patient=E.Patient
AND E2.RecoveryDate IS NOT NULL
)
) AS D;
This is my second code:
DELETE E.* FROM Onset E
INNER JOIN Pathology PA ON E.Pathology = PA.Name
NATURAL JOIN(
SELECT E2.Patient
FROM Onset E2 INNER JOIN Pathology P ON E2.Pathology = P.Name
WHERE E2.RecoveryDate IS NOT NULL
AND P.BodyPart = 'Muscles'
GROUP BY E2.Patient
HAVING COUNT(DISTINCT E2.Pathology) >= 2
) AS D
WHERE PA.BodyPart = 'Muscles'
AND E.RecoveryDate IS NOT NULL;
The second code works fine, instead the first one returns me the common error:
Error Code: 1093. You can't specify target table 'ES' for update in
FROM clause
I know that it happens when you try to delete from a table that you use inside a subquery, and that you can bypass this using a derived table.
Though, both my codes use Onset inside a subquery, and both use a derived table. So, why the first one doesn't work, while the second does?
Thanks in advance!
In delete clause remove the from clause
DELETE ES
NATURAL JOIN
(
SELECT E.Patient, E.Pathology, E.OnsetDate
FROM Onset E INNER JOIN Pathology P ON E.Pathology=P.Name
WHERE P.BodyPart='Muscles'
AND E.RecoveryDate IS NOT NULL
AND 2<=(SELECT COUNT(DISTINCT E2.Pathology)
FROM Onset E2 INNER JOIN Pathology P2 ON E2.Pathology=P2.Name
WHERE P2.BodyPart='Muscles'
AND E2.Patient=E.Patient
AND E2.RecoveryDate IS NOT NULL
)
) AS D;
be sure you have a proper (where) condition;

MySQL Update Row from Query

I've got a complex (For me!) query that basically is grabbing the data from 2 tables then grouping them togeher (This bit works 100% as a SELECT query)
But when I now need to update the database in another table, it won't work.
I've got this:
UPDATE
exp_channel_data data,
(
SELECT
posts.cat_id,
posts.entry_id,
cats.cat_name,
cats.cat_id,
GROUP_CONCAT('{"',cats.cat_name, '"}:{"',cats.cat_name,'"}') as category_tag
FROM
exp_category_posts posts,
exp_categories cats
WHERE
cats.cat_id = posts.cat_id
GROUP BY
posts.entry_id
) category
SET
data.field_id_178 = category.category_tag
WHERE
data.entry_id = category.entry_id;
But I'm getting this error:
Duplicate column name 'cat_id'
I think its because i'm trying to make the connection between the two tables, BUT it's not linking.
Like I said, the SELECT query works on it's own, but when put in to the UPDATE - It just throws this error.
:(
You are very close to what you need:
UPDATE exp_channel_data data JOIN
(SELECT posts.entry_id,
GROUP_CONCAT('{"',cats.cat_name, '"}:{"',cats.cat_name,'"}') as category_tag
FROM exp_category_posts posts JOIN
exp_categories cats
ON cats.cat_id = posts.cat_id
GROUP BY posts.entry_id
) category
ON data.entry_id = category.entry_id
SET data.field_id_178 = category.category_tag;
The important part was removing cats.cat_id from the subquery. You had two columns with that name, confusing MySQL.
I also fixed the query to use proper, explicit JOIN syntax.

MySQL UPDATE with SELECT (mark "item" as read)

I have the following query which selects personal messages (PM) from "ac_pms" table. Additional info is fetching from other table - "ac_accounts" using LEFT JOIN. There is "pm_read" column in "ac_pms" table which define a PM is read or not. I need to set that field (pm_read) to "1" while selecting PMs.
SELECT p.*, a.seller_id, a.winner_id
FROM `ac_pms` AS p
LEFT JOIN `ac_accounts` AS a ON p.pm_for_lot = a.id
WHERE (p.pm_from=[user_id] OR p.pm_to=[user_id])
AND p.pm_for_lot=[account_id]
ORDER BY p.pm_date DESC;
I cannot imagine where to insert UPDATE expression to SET pm_read = 1.
You can't SELECT with UPDATE in the same SQL statement.
However, you can UPDATE with JOIN like this:
UPDATE ac_pms AS p
LEFT JOIN ac_accounts AS a ON p.pm_for_lot = a.id
SET p.pm_read = 1
WHERE (p.pm_from=[user_id] OR p.pm_to=[user_id])
AND p.pm_for_lot = [account_id];
Then you can make another SELECT after that.