getting ids from 3 tables - mysql

a team table which containd a team ID and a team name and then 2 further tables that contain data from a quiz and another with data from a questionnaire.
I need to get a list of team IDs that have completed BOTH the quiz (so have some quiz data) AND the questionnaire (so have some questionnaire data) but I can't see how to join the 3 tables to get the list of ids I need.
Any pointers greatly received

As you said in upper comment..
I actually want team IDs that are in either of the data tables. How
would that amend the query? – Dave
Try this, This is what I understood with your words..
select teamID,teamName from team where teamID in (select teamID from quiz) or teamID in (select teamID from questionnaire);

Assuming you have some reference of team table inside quiz and questionaire tables, you will need to make a join this way -
SELECT team.id, team.name
from
team, quiz, questionnaire
where
team.id=quiz.team_id
AND team.id=questionnaire.team_id
when you do team.id=quiz.team_id AND team.id=questionnaire.team_id only those team IDs which are present in both quiz and questionnaire tables willbe shown in the result.
If you need team ID which exists in either of the tables quiz or questionaire, then you will to replace AND by OR-
SELECT team.id, team.name
from
team, quiz, questionnaire
where
team.id=quiz.team_id
OR team.id=questionnaire.team_id

Related

mySQL: how to go along 3 different tables, referring to different column in each table but using primary keys

I'm trying to find out which schools had students that did not complete their exams in 2018. So I've got 3 tables set up being: ExamInfo, ExamEntry and Students. I'm going to try use the ExamInfo table to get information from the Students table though, I obviously only want the student information that did not complete their exam in 2018. Note: I'm looking for students that attended, though did not complete the exam, with this particular exam you can look at completed exam as passed exam.
Within ExamInfo I have the columns:
ExamInfo_Date --when exam took place, using to get year() condition
ExamInfo_ExamNo --unique student exam ID used to connect with other tables
ExamInfo_Completed --1 if completed, 0 if not.
...
Within ExamEntry I have the related columns:
ExamEntry_ExamNo --connected to ExamInfo table
ExamEntry_StudentId --unique studentId used to connect to Students table
ExamEntry_Date -- this is same as ExamInfo_Date if any relevance.
...
Within Students I have following columns:
Students_Id --this is related to ExamEntry_StudentId, PRIMARY KEY
Students_School --this is the school of which I wish to be my output.
...
I want my output to simply be a list of all schools that had students that did not complete their exams in 2018. Though my issue is with getting from the ExamInfo table, to finding the schools of which students did not complete their exam.
So far I've:
SELECT a.Students_School, YEAR(l.ExamInfo_Date), l.ExamInfo_Completed
FROM ExamInfo l ??JOIN?? Students a
WHERE YEAR(l.ExamInfo_Date) = 2018
AND l.ExamInfo_Completed = 0
;
I'm not even sure if going through the ExamEntry table is necessary. I'm sure I'm meant to use a join, though unsure of how to appropriately use it. Also, with my 3 different SELECT columns, I only wish for Students_School column to be output:
Students_School
---------------
Applederry
Barnet Boys
...
Clearly, you need a JOIN -- two in fact. Your table has exams, students, and a junction/association table that represents the many-to-many relationship between these entities.
So, I would expect the FROM clause to look like:
FROM ExamInfo e JOIN
ExamEntry ee
ON ee.ExamEntry_ExamNo = e.ExamNo JOIN
Students s
ON ee.ExamEntry_StudentId = s.Students_Id

Joining mysql tables on multiple fields

I have a sports site where I have a teams table and a games table. The teams table has the team id, name, and logo(url). The games table has the game id, date, time, hometeamid, and awayteamid.
I'm trying to come up with a mysql query that will return the list of games that includes the associated team names and logos that go with their ids.
Right now, I'm pulling the list of games with their hometeamid and awayteamid, then I'm going back to do a query on the teams table with the hometeamid to get their name and logo, then repeating with the awayteamid to get their name and logo.
That seems like a lot of hitting the db, especially if I can somehow join them in the one first query.
Many thanks for any help you can give.
Let's say you have tables:
TEAM with fields T_ID, NAME, URL
GAME with fields G_ID, T_ID1, T_ID2, others...
A joined select in your case would be:
Select a.G_ID,b.NAME,c.NAME from GAME a, TEAM b, TEAM c where a.T_ID1=c.T_ID and a.T_ID2=b.T_ID
Let us know if you need any more help

How do I merge multiple records in Access 2007 into a single record?

I've searched through numerous discussions and have been unable to find a solution to my particular problem. I have an Access 2007 database with a Faculty table and Sessions table in a many-to-many relationship. Faculty members can be in more than one session and can have different roles (presenter, moderator, facilitator, etc.) depending on which session you look at. I am trying to create a query that lists a faculty member's roles in a single record across all the sessions they are in. Currently, I get a single record for each session that a faculty member is in unless their roles are identical in another session. I want to see their roles across the board independent of the sessions they are in.
I'm part of the way there. Below is the SQL code for the query I currently have.
SELECT DISTINCT
FacultySessionJoin.FacultyID,
Faculty.FirstName,
Faculty.LastName,
Faculty.Email,
FacultySessionJoin.Presenter,
FacultySessionJoin.Moderator,
FacultySessionJoin.Facilitator
FROM
Faculty
LEFT JOIN
FacultySessionJoin ON Faculty.FacultyID = FacultySessionJoin.FacultyID
ORDER BY FacultySessionJoin.FacultyID;
I'd post an image of the results, but the site won't allow me to. Here's an example of my problem:
Faculty ID FirstName LastName Presenter Moderator Facilitator
3 Vanessa Smith Yes
3 Vanessa Smith Yes Yes
How would I combine all such records in my query into a single line such as:
Faculty ID FirstName LastName Presenter Moderator Facilitator
3 Vanessa Smith Yes Yes
How about:
SELECT
FacultySessionJoin.FacultyID,
Faculty.FirstName, Faculty.LastName,
Faculty.Email,
Max(FacultySessionJoin.Presenter),
Max(FacultySessionJoin.Moderator),
Max(FacultySessionJoin.Facilitator)
FROM Faculty
LEFT JOIN FacultySessionJoin
ON Faculty.FacultyID = FacultySessionJoin.FacultyID
GROUP BY
FacultySessionJoin.FacultyID, Faculty.FirstName,
Faculty.LastName, Faculty.Email

MySQL data fetching

I have trouble to understand how to fetch data from MySQL. Answer might by simple, but i'm stuck, and can't find any help over internet...
I have three tables, let's say first table is named series, second is teams and third id games.
Table structure is something like this:
series:
id
name
teams:
id
name
games:
series_id (relates to series.id)
hometeam_id (relates to teams.id)
visitorteam_id (relates to teams.id)
So my problem is fetching rows from games, where those id's need to be there names, not id's...
Result should be something like this:
"championship
wolverines
marines"
not like
"1
45
142"
Currently i'm fetching those series and teams tables to hashref (in perl) and taking id's from there. But there must be more efficient way to do that in one sql query instead of three.
You need to join the teams table twice (once for home team, second time for visitors)
SELECT g.*,h.name as hometeam_name,v.name as visitorteam_name FROM games g
INNER JOIN series s ON g.series_id=s.id
INNER JOIN teams h ON g.hometeam_id=h.id
INNER JOIN teams v ON g.visitorteam_id=v.id

MySQL Multiple interests matching problem

I have a database where users enter their interests. I want to find people with matching interests.
The structure of the interest table is
interestid | username | hobby | location | level | matchinginterestids
Let's take two users to keep it simple.
User Joe may have 10 different interest records
User greg may have 10 different interest records.
I want to do the following algorithm
Take Joe's interest record 1 and look for matching hobbies and locations from the interest database. Put any matching interest id's in the matches field. Then go to joe's interest record 2 etc..
I guess what I need is some sort of for loop that will loop through all of joe's intersts and then do an update each time it finds a match in the interest database. Is that even possible in MySQL?
Further example:
I am Dan. I have 3 interests. Each interest is composed of 3 subjects:
Dan cats,nutrition,hair
Dan superlens,dna,microscopes
Dan film,slowmotion,fightscenes
Other people may have other interests
Joe:
Joe cats,nutrition,strength
Joe superlens,dna,microscopes
Moe
Moe mysql,queries,php
Moe film,specialfx,cameras
Moe superlens,dna,microscopes
Now I want the query to return the following when I log in as Dan:
Here are your interest matches:
--- is interested in cats nutrition hair
Joe is interested in cats and nutrition
Joe and Moe are interested in superlens, dna, microscopes
Moe is interested in film
The query needs to iterate through all Dan's interests, and compare 3,2,1 subject matches.
I could do this in php from a loop but it would be calling the database all the time to get the results. I was wondering if there's a crafty way to do it using a single query Or maybe 3 separate queries one looking for 3 matches, one for 2 and one for 1.
This is definitely possible with MySQL, but I think you may be going about it in an awkward way. I would begin by structuring the tables as follows:
TABLE Users ( userId, username, location )
TABLE Interests( interestId, hobby )
TABLE UserInterests( userId, interestId, level )
When a user adds an interest, if it hasn't been added before, you add it to the Interests table, and then add it to the UserInterests table. When you want to check for other nearby folks with similar interests, you can simply query the UserInterests table for other people who have similar interests, which has all that information for you already:
SELECT DISTINCT userId
FROM UserInterests
WHERE interestId IN (
SELECT interestId
FROM UserInterests
WHERE userId = $JoesID
)
This can probably be done in a more elegant fashion without subqueries, but it's what I thought of now.
As per special request from daniel, although it's kind of duplicate but never mind.
The schema explained
TABLE User (id, username, location )
TABLE Interests(id, hobby )
TABLE UserInterest(userId, interestId, level )
Table users has just user data and a primary key field at the start: id.
The primary key field is a pure link field, the other fields are info fields.
Table Interest again has a primary key that is use to link against and some info field
(ehm well just one, but that's because this is an example)
Note that users and interests are not linked in any way whatsoever.
That's odd, why is that?
Well there is a problem... One user can have multiple intrests and intrests can belong to multiple people.
We can solve this by changing to users table like so:
TABLE users (id, username, location, intrest1, intrest2, intrest3)
But this is a bad, really really bad idea, because:
This way only 3 interests per user are allowed
It's a waste of space if many users have 2, 1 or no interests
And most important, it makes queries difficult to write.
Example query for linking with the bad users table
SELECT * FROM user
INNER JOIN interests ON (user.intrest1 = interests.id) or
(user.intrest2 = interests.id) or
(user.intrest3 = interests.id);
And that's just for a simple query listing all users and their interests.
It quickly gets horribly complex as things progress.
many-to-many relationships
The solution to the problem of a many to many relationship is to use a link table.
This reduces the many-to-many relationship into two 1-to-many relationships.
A: 1 userinterest to many user's
B: 1 userinterest to many interests
Example query using a link-table
SELECT * FROM user
INNER JOIN userInterest ON (user.id = userInterest.userID) //many-to-1
INNER JOIN interest ON (interest.id = userInterest.InterestID); //many-to-1
Why is this better?
Unlimited number of interests per user and visa versa
No wasted space if a user has a boring life and few if any interests
Queries are simpler to maintain
Making it interesting
Just listing all users is not very fun, because then we still have to process the data in php or whatever. But there's no need to do that SQL is a query language after all so let's ask a question:
Give all users that share an interest with user Moe.
OK, lets make a cookbook and gather our ingredients. What do we need.
Well we have a user "Moe" and we have other user's, everybody but not "Moe".
And we have the interests shared between them.
And we'll need the link table userInterest as well because that's the way we link user and interests.
Let's first list all of Moe's Hobbies
SELECT i_Moe.hobby FROM interests AS i_Moe
INNER JOIN userInterests as ui2 ON (ui2.InterestID = i_Moe.id)
INNER JOIN user AS u_Moe ON (u_Moe.id = ui2.UserID)
WHERE u_Moe.username = 'Moe';
Now we combine the select for all users against only Moe's hobbies.
SELECT u_Others.username FROM interests AS i_Others
INNER JOIN userinterests AS ui1 ON (ui1.interestID = i_Others.id)
INNER JOIN user AS u_Others ON (ui1.user_id = u_Others.id)
/*up to this point this query is a list of all interests of all users*/
INNER JOIN Interests AS i_Moe ON (i_Moe.Hobby = i_Others.hobby)
/*Here we link Moe's hobbies to other people's hobbies*/
INNER JOIN userInterests as ui2 ON (ui2.InterestID = i_Moe.id)
INNER JOIN user AS u_Moe ON (u_Moe.id = ui2.UserID)
/*And using the link table we link Moe's hobbies to Moe*/
WHERE u_Moe.username = 'Moe'
/*We limited user-u_moe to only 'Moe'*/
AND u_Others.username <> 'Moe';
/*and the rest to everybody except 'Moe'*/
Because we are using INNER JOIN's on link fields only matches will be considered and non-matches will be thrown out.
If you read the query in english it goes like this.
Consider all users who are not Moe, call them U_others.
Consider user Moe, call him U_Moe.
Consider user Moe's Hobbies, call those i_Moe
Consider other users's Hobbies, call those i_Others
Now link i_Others hobbies to u_Moe's Hobbies
Return only users from U_Others that have a hobby that matches Moe's
Hope this helps.