OneToMany relationship. How to delete row? - mysql

Hello. I have just learned how to select all related data to, say, the row
tennismatch.ID = 1:
SELECT * FROM tennismatch m
JOIN tennismatch_tennisset ms
ON m.`ID` = ms.`TennisMatch_ID`
JOIN tennisset s
ON ms.`mapOfSets_ID` = s.`ID`
JOIN tennisset_game sg
ON s.`ID` = sg.`TennisSet_ID`
JOIN game g
ON sg.`gamesMap_ID` = g.`ID`
JOIN game_point gp
ON g.`ID` =gp.`Game_ID`
JOIN point p
ON gp.`points_ID` = p.`ID`
WHERE m.`ID` = 1
but I cannot figure how to delete it ALL.
Big thanks in advance.

Use a DELETE JOIN statement
DELETE m, s, g, p, ms, sg, gp
FROM tennismatch m
JOIN tennismatch_tennisset ms ON m.ID = ms.TennisMatch_ID
JOIN tennisset s ON ms.mapOfSets_ID = s.ID
JOIN tennisset_game sg ON s.ID = sg.TennisSet_ID
JOIN game g ON sg.gamesMap_ID = g.ID
JOIN game_point gp ON g.ID = gp.Game_ID
JOIN point p ON gp.points_ID = p.ID
WHERE m.ID = 1

Related

DELETE with multiple JOIN in MySQL?

I have a SELECT query with multiple JOIN who works perfectly, but now I want to DELETE this rows, and I can't find how.
This code returns me an error SQL (1064):
DELETE FROM rapport
INNER JOIN course ON rapport.course_id = course.id
INNER JOIN reunion ON course.reunion_id = reunion.id
INNER JOIN paris ON rapport.paris_id = paris.id
WHERE reunion.id = 231431
AND paris.bookmaker_id = 3
I need some help, thanks
Your syntax is wrong.
Use this with aliases also:
DELETE r
FROM rapport r
INNER JOIN course c ON r.course_id = c.id
INNER JOIN reunion u ON c.reunion_id = u.id
INNER JOIN paris p ON r.paris_id = p.id
WHERE u.id = 231431 AND p.bookmaker_id = 3
If you want to delete from all tables then you must specify their aliases after DELETE:
DELETE r, c, u, p
FROM rapport r
INNER JOIN course c ON r.course_id = c.id
INNER JOIN reunion u ON c.reunion_id = u.id
INNER JOIN paris p ON r.paris_id = p.id
WHERE u.id = 231431 AND p.bookmaker_id = 3
Basically, you need to specify what table to delete from. Assuming this is rapport:
DELETE r
FROM rapport r JOIN
course c
ON r.course_id = c.id JOIN
reunion ru
ON c.reunion_id = ru.id JOIN
paris p
ON r.paris_id = p.id
WHERE ru.id = 231431 AND p.bookmaker_id = 3;
MySQL also supports deletion from multiple tables. However, cascading constraints are usually a better approach.

Convert query with exists to joins

I want to convert this query in such a way so it does not have any 'exists' and uses only simple joins.
select t.Teacher_id, t.Teacher_name, a.marks, a.grade_ID
from Grades a
left join students s on a.student_ID = s.student_ID
left join Teachers t on t.Teacher_ID = s.Teacher_ID
where 1=1 and t.Teacher_id = 1807600
and exists(
select p.Payment_ID from payments p
inner join lookups l on (l.lookup_id = p.status_id and l.lookup_key in ('condition1','condition2'))
where p.student_ID = a.student_ID
)
I tried something like:
select t.Teacher_id, t.Teacher_name, a.marks, a.grade_ID
from Grades a
left join students s on a.student_ID = s.student_ID
left join Teachers t on t.Teacher_ID = s.Teacher_ID
inner join payments p on p.student_ID = a.student_ID
inner join lookups l on (l.lookup_id = p.status_id and l.lookup_key in ('condition1','condition2'))
where 1=1 and t.Teacher_id = 1807600
But I'm not getting the right results. Can you please help. Thanks.
I suppose you could use group by, but this restricts the maintainability of the script for the simple sake of not using EXISTS().
select t.Teacher_id, t.Teacher_name, a.marks, a.grade_ID
from Grades a
left join students s on a.student_ID = s.student_ID
left join Teachers t on t.Teacher_ID = s.Teacher_ID
inner join payments p on p.student_ID = a.student_ID
inner join lookups l on (l.lookup_id = p.status_id and l.lookup_key in ('condition1','condition2'))
where t.Teacher_id = 1807600
group by t.Teacher_id, t.Teacher_name, a.marks, a.grade_ID

How to inner join for the resultted query in mysql

I have an mysql query for getting which user assigned to which course and if the course having certificate then only the results will be prints. for this i am using inner join with many table. Here is the code :
SELECT DISTINCT c.fullname,usr.id, usr.username, usr.email, c.enrolenddate
FROM m_tl_course AS c
INNER JOIN m_tl_context AS cx ON c.id = cx.instanceid AND cx.contextlevel = '50'
INNER JOIN m_tl_role_assignments AS ra ON cx.id = ra.contextid
INNER JOIN m_tl_role AS r ON ra.roleid = r.id
INNER JOIN m_tl_user AS usr ON ra.userid = usr.id
INNER JOIN m_tl_certificate AS ce ON ce.course = c.id
WHERE r.name = "Student" and ra.timeend = '0'
I have an another table to having data's like the user's who's download their certificate. The table name is m_tl_certification.
In this table having Columns like, user_id ( this the user id), Course_id (this is the course id), cert_date ( this is the certificate download date).
What i want is i want to get the user's who is not download their certicate.
How to get this. please can anyone help me ?
What will be the column value if not downloaded and if downloaded. If the Download date is NULL then in where add Download_Date IS NULL
SELECT DISTINCT c.fullname,usr.id, usr.username, usr.email,c.enrolenddate
FROM m_tl_course AS c
INNER JOIN m_tl_context AS cx ON c.id = cx.instanceid AND cx.contextlevel = '50'
INNER JOIN m_tl_role_assignments AS ra ON cx.id = ra.contextid
INNER JOIN m_tl_role AS r ON ra.roleid = r.id
INNER JOIN m_tl_user AS usr ON ra.userid = usr.id
INNER JOIN m_tl_certificate AS ce ON ce.course = c.id INNER JOIN m_tl_certificate AS ce ON ce.course = c.id
INNER JOIN m_tl_certification As cee ON cee.user_id = usr.id
WHERE r.name = "Student" and ra.timeend = '0' and cee.downloadDate IS NULL
Modify your query with the following
SELECT DISTINCT c.fullname,usr.id, usr.username, usr.email, c.enrolenddate
FROM m_tl_course AS c
INNER JOIN m_tl_context AS cx ON c.id = cx.instanceid AND cx.contextlevel = '50'
INNER JOIN m_tl_role_assignments AS ra ON cx.id = ra.contextid
INNER JOIN m_tl_role AS r ON ra.roleid = r.id
INNER JOIN m_tl_user AS usr ON ra.userid = usr.id
LEFT JOIN m_tl_certificate AS ce ON ce.course = c.id
WHERE r.name = "Student" and ra.timeend = '0'

Query goes wrong when checking if the user exists in other table

I have a query that shows a list of revisions and employees for every revision..
Now I'm trying to show if the given employee already has a row in the answers table..
This is the overview of the database
This is my working query that shows the list of revisions and employees
SELECT l.id, l.naam, r.id as revision_id, r.beschrijving, e.id as employee_id, e.voornaam, e.achternaam,
FROM lists l
INNER JOIN revisions r ON l.id = r.list_id
INNER JOIN employeelists el ON el.list_id= l.id
INNER JOIN employees e ON e.id = el.employee_id
INNER JOIN customers c ON c.id = e.customer_id
WHERE customer_id = :id AND r.actief = 1
Now I've tried several things to see if the employee already has a record in the answers table.. But It's failing the whole time..
Try 1 : Adding the Answers table with a left outer join
SELECT l.id, l.naam, r.id as revision_id, r.beschrijving, e.id as employee_id, e.voornaam, e.achternaam,
**CASE WHEN a.coach_id != 0 THEN 1 ELSE 0 END as FILLED IN**
FROM lists l"""
INNER JOIN revisions r ON l.id = r.list_id
**LEFT OUTER JOIN answers a ON a.revision_id = r.id**
INNER JOIN employeelists el ON el.list_id= l.id
INNER JOIN employees e ON e.id = el.employee_id
INNER JOIN customers c ON c.id = e.customer_id
WHERE customer_id = :id AND r.actief = 1
now the problem is that every employee is shown multiple times...
This is the SQLFiddle of the working database, The only thing i can't do is check if the given employee ( werknemer ) exists in the answers ( antwoorden ) table..
http://sqlfiddle.com/#!2/0c01c/4
Any idea on how i can solve this? I tried a subquery, but that didn't work out either.. Thanks!
Problem with Query Now
I thought i was correct but there's one more error. in the answers table, it shows results for werknemer_id ( employee_id ) = 78. For the revisie ( revision ) 1 and 2
While there is only results for revisie 1 (screenshot below)
Thanks!
How about this exist column will have 0 if not in antwoorden and 1 if exist
SELECT l.id, l.naam, r.revisie as revisie, r.id as revisie_id, r.beschrijving, w.id as werknemer, w.voornaam, w.achternaam
, a.werknemer_id,
(CASE WHEN a.werknemer_id IS NULL THEN 0 ELSE 1 END ) AS `exist`
FROM lijsten l
INNER JOIN revisies r ON l.id = r.lijst_id
INNER JOIN werknemerlijsten wl ON wl.lijst_id = l.id
INNER JOIN werknemers w ON w.id = wl.werknemer_id
INNER JOIN klanten k ON k.id = w.klant_id
LEFT JOIN antwoorden a ON w.id = a.werknemer_id
WHERE klant_id = 39 AND r.actief = 1
GROUP BY r.beschrijving, w.id
Fiddle
Final solution
This is the final outcome, only see 'ingevuld' is 1 if the desired coach (1 in thise case) is in the answers table.
SELECT l.id, l.naam, r.revisie AS revisie, r.id AS revisie_id, r.beschrijving, w.id AS werknemer, w.voornaam, w.achternaam, a.coach_id,
CASE WHEN a.coach_id = 1 THEN 1 ELSE 0 END AS ingevuld
FROM lijsten l
INNER JOIN revisies r ON l.id = r.lijst_id
INNER JOIN werknemerlijsten wl ON wl.lijst_id = l.id
INNER JOIN werknemers w ON w.id = wl.werknemer_id
INNER JOIN klanten k ON k.id = w.klant_id
LEFT JOIN antwoorden a ON w.id = a.werknemer_id AND r.id=a.revisie_id
WHERE klant_id = 39 AND r.actief = 1
group by r.id, w.id, a.coach_id

only returning records when s.id = u.summary_id

select
s.id, s.description, s.improvement, s.previous_year_id,
s.current_year_id, s.first_name, s.last_name, s.username,
s.finding, s.action, s.share, s.learned, s.timestamp,
d.title as department_title,
group_concat(g.title SEPARATOR \' | \') as strategic_goals,
y1.year as current_year_title, y2.year as previous_year_title,
u.summary_id, u.file_name as file_name
from
summary s, year y1, year y2, strategic_goal_entries sge,
goal g, department d, uploads u
where
s.id = sge.summary_id
and
s.current_year_id = y1.id
and
s.previous_year_id = y2.id
and
sge.goal_id = g.id
and
s.id = u.summary_id
and
s.department_id = d.id
and
s.department_id = '4'
group by
s.id
This only returns records from the summary table that has a relating record in the uploads table (s.id = uploads.summary_id) that contain a value within the uploads.summary_id field
I want to return all records, whether or not it has a file associated with it.
Any help is appreciated.
Suggest refactoring this SQL query to use ANSI joins. To achive your goal, you'd want a LEFT JOIN instead:
SELECT /*your columns*/
from summary s
INNER JOIN year y1 ON s.current_year_id = y1.id
INNER JOIN year y2 ON s.previous_year_id = y2.id
INNER JOIN strategic_goal_entries sge ON s.id = sge.summary_id
INNER JOIN goal g ON sge.goal_id = g.id
INNER JOIN department d ON s.department_id = d.id
LEFT JOIN uploads u ON s.id = u.summary_id
WHERE s.department_id = '4'
group by s.id