use multiple results of a query within the query with joins - mysql

I have some tables in my database, three main ones and one that holds the many-to-many relations.
1. Student (student_id, student_name)
2. Sport (sport_id, sport_name)
3. Departm (depart_id, depart_name)
4. Sch (sch_id, sch_name)
5. StudSport(relationid, studendid, sportid, departid, schid)
What I want to do is e.g. retrieve the name of the department based on the relations when I know the id. I can get the ids like this:
SELECT departid, schid from studsport
inner join Student on student_id = studentid
inner join Sport on sport_id = sportid
where student_id = 1 and sport_id=2
but I want to get the names of the department and the Sch from their corresponding tables, and I dont know how to do that.

As you don't select anything from Student or Sport, you can remove the corresponding inner joins.
SELECT d.depart_name, sch.sch_name FROM StudSport s
INNER JOIN Sch sch ON s.schid = sch.sch_id
INNER JOIN Departm d ON s.departid = d.depart_id
WHERE s.studendid = 1 AND s.sportid = 2

Something like this???
select sch.sch_nam, departm.depart_name,
-- what you have already --
Left outer Join StudSport on Student.student_id = Studsport.studentid and Sport.sport_id = StudSport.sportid
left outer Join Sch on StudSport.schid = Sch.sch_id
left outer join Departm on studsport.depart_id = studsport.departid
This is untested, a fiddle makes it much easier to give answers because of that.
EDIT - I misread your original query - before the downvotes start to rain - fixing it right now.
The way you should use LEFT OUTER and INNER joins is how the data is meant (again, a fiddle will normally be usefull) but it's just a couple of joins from what you have i guess:
select *
from studsport
join student on studsport.studentid = student.student_id
join sport on studsport.sportid = sport.sport_id
left outer Join Sch on StudSport.schid = Sch.sch_id
left outer join Departm on studsport.depart_id = studsport.departid
where student_id = 1 and sport_id=2

Related

How to get mysql query with table reference?

I have two tables like below
master and transaction table
How to view table like below...?
result
i have tried to use inner join or left join but cannot find like i need
Thank you
You can easily achieve it with the help of LEFT JOIN. Please try below queries:
For person id P01:
SELECT fruits.id_fruits, fruits.name, choice.person_id
FROM fruits LEFT JOIN choice
ON choice.id_fruits = fruits.id_fruits
AND choice.person_id = 'P01' ORDER BY fruits.id_fruits;
For person id P02:
SELECT fruits.id_fruits, fruits.name, choice.person_id
FROM fruits LEFT JOIN choice
ON choice.id_fruits = fruits.id_fruits
AND choice.person_id = 'P02' ORDER BY fruits.id_fruits;
For person id P03:
SELECT fruits.id_fruits, fruits.name, choice.person_id
FROM fruits LEFT JOIN choice
ON choice.id_fruits = fruits.id_fruits
AND choice.person_id = 'P03' ORDER BY fruits.id_fruits;
Try queries at https://www.db-fiddle.com/f/5RE6V6p9JLQ9VomCVXqKMa/1
SELECT id_fruit,name,person_id FROM FROM Fruits LEFT JOIN choice USING (id_fruits) WHERE person_id=... ODER BY id_fruits;
or for all
SELECT id_fruit,name,person_id FROM FROM Fruits LEFT JOIN choice USING (id_fruits) ODER BY id_fruits,person_id;

MySQL how to select what I need, most likely an inner join

A bit of a newbie question, probably an INNER JOIN with an "AS" statement, but I can't figure it out...
This is for a MYSQL based competition app. I want to select the "img_title" for both img_id1 and img_id2. I can't figure out how to do it and still see which title is assigned to the associated _id1 or _id2.
My tables:
competitions
comp_id
img_id1
img_id2
on_deck
img_id
img_title
Desired results:
comp_id | img_id1 | img_title1 |img_id2 | img_title2
You need a join for each image:
SELECT comp.comp_id, img1.img_id, img1.img_title, img2.img_id, img2.img_title
FROM competitions comp
INNER JOIN on_deck img1 ON img1.img_id = comp.img_id1
INNER JOIN on_deck img2 ON img2.img_id = comp.img_id2
LEFT JOIN if img_id1 or img_id2 can be NULL.
select comp_id, img_id1, b.img_title as img_title1,
img_id2, b2.img_title as img_title2
from competitions a
left outer join on_deck b on b.img_id = a.img_id1
left outer join on_deck b2 on b2.img_id = a.img_id2
switch let outer join to inner join if you want to exclude rows in competitions that do not have two matching img_ids
This query should give you the results you want. This also assumes that comp.img_id1 and comp.img_id2 are never NULL.
SELECT comp.comp_id
, comp.img_id1
, deck1.img_title AS img_title1
, comp.img_id2
, deck2.img_title AS img_title2
FROM competitions AS comp
JOIN on_deck deck1 ON comp.img_id1 = deck1.img_id
JOIN on_deck deck2 ON comp.img_id2 = deck2.img_id
If you have plan on having a NULL or empty string comp.img_id1 and/or comp.img_id2 fields, you'll need to do some left joins.

Need some assistance with a complex JOIN is SQL Query

Take a look at these tables
It's simple: Venue contains country_ID which is an FK in Society_Territory where we will find a society_ID which is an FK of Society. I have a Venue_ID during the query and my objective is to get the Society_Name but there is a twist but first lets just get the Society_Name
In the following query only look at JOINS and in there I am gonna add comments with this // prefix
SELECT
uuid()AS `UUID`,
`pc`.`PRSClaimID` AS `prsclaimid`,
`a`.`LoginName` AS `loginname`,
`a`.`BandName` AS `bandname`,
`smartistdetails`.`LoginName` AS `createdbyloginname`,
`Society`.`Society_Name` AS societyName
count(
`smliveclaims`.`LiveclaimsID`
)AS `gigcount`
FROM `smprsliveclaimlink`
JOIN `smliveclaims` ON `smprsliveclaimlink`.`fkLiveClaimID` = `smliveclaims`.`LiveclaimsID`
// Here I have the Venue_ID from smliveclaims so i starting moving towards society name
JOIN Venue ON `smliveclaims`.fk_venueId = Venue.Venue_ID
JOIN Society_Territory ON Venue.Country_ID = Society_Territory.Country_ID
JOIN Society ON Society_Territory.Society_Id = Society.Society_ID
// Now from Society i can select the Society_Name which i am already doing in the query above
JOIN `smartistdetails` `a`
JOIN `smprsclaims` `pc` ON `a`.`ArtistID` = `pc`.`fkArtistID`
JOIN `smcategories` ON `pc`.`FK_CategoryID` = `smcategories`.`Id`
JOIN `smcategoriestype` ON `smcategories`.`fk_CategoryTypeId` = `smcategoriestype`.`Id`
JOIN `smartistdetails` ON `pc`.`CreatedBy` = `smartistdetails`.`ArtistID` AND `smprsliveclaimlink`.`fkPRSClaimID` = `pc`.`PRSClaimID`
GROUP BY
`a`.`LoginName`,
`a`.`BandName`,
`smcategories`.`Id`,
`smcategoriestype`.`CategoryType`,
`smartistdetails`.`LoginName`
All is cool till here. Now here is the TWIST
I will have Country_IDs in Venue which will not be in Society_Territory. And I still want to select them and instead of showing and actual Society_Name want to show a word such as "Other"
use a LEFT OUTER JOIN when you link VENUE with SOCIETY_TERRITORY and so on when you link SOCIETY_TERRITORY with SOCIETY
Pay attention: When you use a LEFT OUTER JOIN all tables depends by its must be linked with other LEFT OUTER JOIN because if you use INNER JOIN you cancel di effects on LEFT.
Edit:
SELECT
uuid()AS `UUID`,
`pc`.`PRSClaimID` AS `prsclaimid`,
`a`.`LoginName` AS `loginname`,
`a`.`BandName` AS `bandname`,
`smartistdetails`.`LoginName` AS `createdbyloginname`,
coalesce(`Society`.`Society_Name`, 'Other') AS societyName
count(`smliveclaims`.`LiveclaimsID`)AS `gigcount`
FROM `smprsliveclaimlink`
JOIN `smliveclaims`
ON `smprsliveclaimlink`.`fkLiveClaimID` = `smliveclaims`.`LiveclaimsID`
// Here I have the Venue_ID from smliveclaims so i starting moving towards society name
JOIN Venue ON `smliveclaims`.fk_venueId = Venue.Venue_ID
LEFT OUTER JOIN Society_Territory ON Venue.Country_ID = Society_Territory.Country_ID
LEFT OUTER JOIN Society ON Society_Territory.Society_Id = Society.Society_ID
// Now from Society i can select the Society_Name which i am already doing in the query above
JOIN `smartistdetails` `a`
JOIN `smprsclaims` `pc` ON `a`.`ArtistID` = `pc`.`fkArtistID`
JOIN `smcategories` ON `pc`.`FK_CategoryID` = `smcategories`.`Id`
JOIN `smcategoriestype` ON `smcategories`.`fk_CategoryTypeId` = `smcategoriestype`.`Id`
JOIN `smartistdetails` ON `pc`.`CreatedBy` = `smartistdetails`.`ArtistID` AND `smprsliveclaimlink`.`fkPRSClaimID` = `pc`.`PRSClaimID`
GROUP BY
`a`.`LoginName`,
`a`.`BandName`,
`smcategories`.`Id`,
`smcategoriestype`.`CategoryType`,
`smartistdetails`.`LoginName`
All your JOINs are INNER JOINs. The INNER keyword is optional in MySQL and frequently omitted (as in your example). Use a LEFT OUTER JOIN where required and amend your SELECT clause to include something like "COALESCE(Society_Name,'Other') Society_Name"

joined query to return data

I have the following query which returns data only if the join exists. How do I return from the last joined table (#__unis) datas, even if there is no relationship between those tables without to write another query?
select * from #__unis_faculties AS faculty
join #__unis_subjects AS subject ON subject.faculty = faculty.id
join #__unis AS uni ON uni.id= subject.university
where uni.id = 1
table structure http://sqlfiddle.com/#!2/19add
use LEFT JOIN instead of join
select * from #__unis_faculties AS faculty
join #__unis_subjects AS subject ON subject.faculty = faculty.id
right join #__unis AS uni ON uni.id= subject.university
where uni.id = 1
Try this..
select * from #__unis_faculties AS faculty
join #__unis_subjects AS subject ON subject.faculty = faculty.id
left join #__unis AS uni ON ( uni.id= subject.university AND uni.id = 1 )

MySQL join & search

I have a problem with joining some tables, heres my structure:
tbl_imdb:
fldID fldTitle fldImdbID
1 Moviename 0000001
tbl_genres:
fldID fldGenre
1 Action
2 Drama
tbl_genres_rel:
fldID fldMovieID fldGenreID
1 1 1
2 1 2
What I’m trying to do is a query that will find all movies that is both an action movie and drama, is this possible to do without a subquery, if so, how?
What I'm trying right now is:
SELECT tbl_imdb.*
FROM tbl_imdb
LEFT JOIN tbl_imdb_genres_rel ON ( tbl_imdb.fldID = tbl_imdb_genres_rel.fldMovieID )
LEFT JOIN tbl_imdb_genres ON ( tbl_imdb_genres_rel.fldGenreID = tbl_imdb_genres.fldID )
WHERE tbl_imdb_genres.fldGenre = 'Drama'
AND tbl_imdb_genres.fldGenre = 'Action';
But this dosnt work, however it does work if I only keep one of the two WHERE's, but thats not what I want.
Two ways to do it:
1
SELECT tbl_imdb.*
FROM tbl_imdb
INNER JOIN tbl_genres_rel rel_action
ON tbl_imdb.fldID = rel_action.fldMovieID
INNER JOIN tbl_genres genre_action
ON rel_action.fldGenreId = genre_action.fldID
AND 'Action' = genre_action.fldGenre
INNER JOIN tbl_genres_rel rel_drama
ON tbl_imdb.fldID = rel_drama.fldMovieID
INNER JOIN tbl_genres genre_drama
ON rel_drama.fldGenreId = genre_drama.fldID
AND 'Drama' = genre_drama.fldGenre
This method is on the same path as your original solution. 2 differences:
The join should be inner, not left because you're trying to get movies that certainly have the corresponding genre entry
Since you want to find 2 different generes, you'll have to do the join with tbl_genres_rel and tbl_genres twice, once for each particular genre you're interested in.
2
SELECT tbl_imdb.*
FROM tbl_imdb
INNER JOIN tbl_genres_rel
ON tbl_imdb.fldID = tbl_genres_rel.fldMovieID
INNER JOIN tbl_genres
ON tbl_genres_rel.fldGenreId = tbl_genres.fldID
AND tbl_genres.fldGenre IN ('Action', 'Drama')
GROUP BY tbl_imdb.fldID
HAVING COUNT(*) = 2
Again, the basic join plan is the same. Difference here is that we join to the tbl_genres_rel and tbl_genres path just once. This on itself fetches all genres for one film, and then filters for the one's you're interested in. The ones that qualify will now have 2 rows for each distinct value of tbl_imdb.fldId. The GROUP BY aggregates on that, flattening that into one row. By asserting in the HAVING clause that we have exactly 2 rows, we ensure that we keep only those rows that have both the genres.
(Note that this assumes that there is a unique constraint on tbl_genres_rel over {fldMovieID, fldGenreID}. If such a constraint is not present, you should consider adding it.)
LEFT JOIN is not applicable in your case because records should exist on both tables. And you need to count the instances of the movie
SELECT *
FROM tbl_imdb a
INNER JOIN tbl_genres_rel b
on a.fldID = fldMovieID
INNER JOIN tbl_genres c
on c.fldGenreID = b.fldID
WHERE c.fldGenre IN ('Drama', 'Action')
GROUP BY a.Moviename
HAVING COUNT(*) > 1