Microsoft Access SQL Joins - ms-access

List all players and their ages for their associated current team for teams that have a manager.
Here are my 3 Tables and their attributes
PLAYER
PLAYERNUM Primary Key
PLAYERNAME
PlayerAge
TEAM
TEAMNUM Primary Key
TEAMNAME
TeamCity
MgrNum
AFFILIATION
PLAYERNUM Primary Key/Foreign Key
TEAMNUM Primary Key/Foreign Key
AffilYrs
AffilBatAvg
AffilDateStart Foreign Key
AffilDateEnd
AffilCurrentTeam
Here is my SQL:
SELECT PLAYERNAME, PlayerAge
FROM PLAYER INNER JOIN AFFILIATION
ON PLAYER.PLAYERNUM = AFFILIATION.PLAYERNUM
INNER JOIN TEAM
ON AFFILIATION.TEAMNUM = TEAM.TEAMNUM
WHERE MgrNum IS NOT NULL;
I am given the error missing operator in query expression

Perhaps it should be;
[NotTested]
SELECT PLAYERNAME, PlayerAge
FROM (PLAYER INNER JOIN AFFILIATION
ON PLAYER.PLAYERNUM = AFFILIATION.PLAYERNUM)
INNER JOIN TEAM
ON AFFILIATION.TEAMNUM = TEAM.TEAMNUM
WHERE MgrNum IS NOT NULL;
GROUP BY PLAYER.PLAYERNAME, PLAYER.PlayerAge
You should use parentheses for multiple joins in access.

Related

Two foreign keys referencing same column

I have two Tables : Livestream and Team.
Livestream:
id_livestream int primary key
id_team1 int
id_team2 int
// I had already referenced these two columns to Team id_team column
Team:
id_team int primary key
name_team varchar(40)
image_team varchar(255)
I want to select name_team from Team for both referenced columns in Livestream..
as example i want to show something like:
id_team1| name of team1| image of team1 | id_team2| name of team 2| image of team2
You can generate the output you want by simply doing two joins from the Livestream table to the Team table:
SELECT
lm.id_team1,
t1.name_team AS name_team_1,
t1.image_team AS image_team_1,
lm.id_team2,
t2.name_team AS name_team_2,
t2.image_team AS image_team_2
FROM Livestream lm
INNER JOIN Team t1
ON lm.id_team1 = t1.id_team
INNER JOIN Team t2
ON lm.id_team2 = t2.id_team
I assume here that every team appearing in Livestream will have an entry somewhere in the Team table. If this be not the case, and you don't want NULL values appearing in your result set, then you can switch to using a LEFT JOIN along with COALESCE().
Try this:
SELECT
ls.id_team1,
t1.name_team AS name_team_1,
t1.image_team AS image_team_1,
ls.id_team2,
t2.name_team AS name_team_2,
t2.image_team AS image_team_2
FROM Livestream ls
INNER JOIN Team t1
ON ls.id_team1 = t1.id_team
INNER JOIN Team t2
ON ls.id_team2 = t2.id_team
Inner join two times with Team does the trick.

how does the count function in mysql work?

First and foremost, this is part of an assignment, but I'm trying to get more clarification on how the count() function works when querying a db.
The question is: List the name, SSN and the number of courses the student has taken (courses with the same CourseNumber taken in different quarters are counted as different courses).
I've been querying using this:
SELECT S.Name, S.SSN, COUNT(*)
FROM Student S, Enrollment E
WHERE S.SSN = E.SSN
GROUP BY S.SSN
which seems to return the correct answer, but I'm not sure why. As a result, I can't seem to get the next questions (assuming courses with the same CourseNumber taken in different quarters are considered as one course) correct.
Here are the create table commands so you can see which table holds what info:
CREATE TABLE Student(
SSN INT(9),
Name VARCHAR(20),
Major VARCHAR(30),
PRIMARY KEY (SSN)
);
CREATE TABLE Course(
CourseNumber INT(5),
PrerequisiteCourseNumber INT(10),
CourseTitle VARCHAR(10),
NumberUnits INT(2),
PRIMARY KEY (CourseNumber)
);
CREATE TABLE Section(
CourseNumber INT(5),
Quarter VARCHAR(10),
RoomNumber INT(5),
DayTime VARCHAR(20),
PRIMARY KEY (CourseNumber,Quarter),
FOREIGN KEY (CourseNumber) REFERENCES Course(CourseNumber)
);
CREATE TABLE Enrollment(
SSN INT(9),
CourseNumber INT(5),
Quarter VARCHAR(10),
Grade VARCHAR(1),
PRIMARY KEY (SSN,CourseNumber,Quarter),
FOREIGN KEY (SSN) REFERENCES Student(SSN),
FOREIGN KEY (CourseNumber) REFERENCES Course(CourseNumber),
FOREIGN KEY (Quarter) REFERENCES Section(Quarter)
);
Any pointers?
what you are doing is using old join syntax (pre ansi syntax) where you do a cross join of tables and use the where to turn it into a join. an equivalent query would be this.
SELECT S.Name, S.SSN, COUNT(*)
FROM Student S
JOIN Enrollment E ON S.SSN = E.SSN
GROUP BY S.SSN
Now to answer your question about what the count is doing and stuff..
COUNT() returns a count of every row that is returned.
GROUP BY groups all of the records by a common ground aka your SSN field. so if a student has 5 SSN rows in the table then his count will be 5.
Now for the part you are looking for with course numbers.. you need to JOIN those tables on appropriate fields and add a field to your group by for each quarter
aka add to the previous code..
WHERE E.quarter = whatever_quarter_you_want
you can add more to this query if you need to. but add data to your question if you want a more full answer.
Your current query is:-
SELECT S.Name, S.SSN, COUNT(*)
FROM Student S
INNER JOIN Enrollment E
ON S.SSN = E.SSN
GROUP BY S.SSN
What this is doing is joining student to enrollment, so giving multiple rows for each student, one for each course / quarter they are enrolled on. It is then grouped by SSN (student number?) to count up the number of course / quarters they are enrolled on. You should really group by S.Name as well (while MySQL won't object, most flavours of SQL would).
Note that COUNT(*) counts the number of rows. You could use COUNT(E.CourseNumber) which would count the number of rows where course number is not null. Not really useful here, but can be useful with LEFT OUTER JOINs. You can also use COUNT(DISTINCT CourseNumber) to count the number of unique non null course numbers for the student.
A LEFT OUTER JOIN might also be better as this would enable you to return 0 as the counts for students who exist but who are not enrolled in any courses:-
SELECT S.Name, S.SSN, COUNT(DISTINCT E.CourseNumber)
FROM Student S
LEFT OUTER JOIN Enrollment E
ON S.SSN = E.SSN
GROUP BY S.Name, S.SSN
SELECT S.Name, S.SSN, COUNT(*)
FROM Student S, Enrollment E, Section Sec, Course C
WHERE S.SSN = E.SSN AND E.CourseNumber = Sec.CourseNumber
AND Sec.CourseNumber = C.CourseNumber AND Sec.Quarter like E.Quarter
GROUP BY S.Name, S.SSN

How to display information from a referencing table?

There is probably a very simple solution to this, but I couldn't figure out an appropriate way to google it.
I have three tables in my database.
The first one is "customer" and it has (ID, Name, Username etc)
The second one is "attraction" and it has (AttractionID, Name, Location, etc..)
The tird one "favourites" is made in order for the user to save favourites from the second table with the user ID from the first one:
Here is the third table:
CREATE TABLE Favorites (
FavID INT NOT NULL,
ID INT NOT NULL,
AttractionID INT NOT NULL,
PRIMARY KEY (FavID),
FOREIGN KEY (ID) REFERENCES customer(ID),
FOREIGN KEY (AttractionID) REFERENCES attraction(AttractionID)
);
I can insert into the table but what sql query do I need to use in order to show information from the referencing tables?
Lets say the user has saved their user ID and favourite attraction ID to the favourite table, how can I display the name and location from the attraction table that corespond to the foreign key attractionID saved in the favourites table?
Thanks
You should use JOIN for it:
SELECT * FROM Favorites f
INNER JOIN Attraction a ON f.AttractionId = a.AttractionId
INNER JOIN customer c ON f.Id = c.id
f, a and c are just aliases to make the referencing simpler, you could also write
SELECT * FROM Favorites
INNER JOIN Attraction ON Favorites.AttractionId = Attraction.AttractionId
INNER JOIN customer ON Favorites.Id = customer.id
or with AS, which makes it a bit more clear (but longer, so I prefer the first way)
SELECT * FROM Favorites AS f
INNER JOIN Attraction AS a ON f.AttractionId = a.AttractionId
INNER JOIN customer AS c ON f.Id = c.id

MySQL one table inner join with 3 different entity tables

I got 4 tables, Email_Company_Contact_Ref table is the table which linked with Email, Company, and Contact.
**Email_Company_Contact_Ref**
id = primary key
email_id = reference to Email.`id`
ref_id = it can be Company.id / Contact.id
table = reference from which table name
I try to use left join to get my output, but I got duplicated result. If I try inner join, I will not get any result at all, it is because Company and Contact this two tables does not have any thing common.
This is the output I would like to complete.
I able to use UNION to get the output, but it not really effective. I am thinking it should be a way to get the output result.. Please help.
Thanks!
Here is my mysql answer, hope this can help
SELECT e.email, r.table, c1.name AS company_name, c2.name AS contact_name
FROM email_company_contact_ref r
JOIN email e ON e.id = r.email_id
LEFT JOIN company c1 ON (c1.id = r.ref_id AND r.table = 'company')
LEFT JOIN contact c2 ON (c2.id = r.ref_id AND r.table = 'contact')
GROUP BY r.table, e.email
I don't think it can be done without a UNION. Here's my suggestion.
SELECT email_address, eccr.table table, company_name, contact_name
FROM Email e, Email_Company_Contact_Ref eccr,
(SELECT "Company" table, id, company_name, NULL contact_name
FROM Company
UNION ALL
SELECT "Contact" table, id, NULL company_name, contact_name
FROM Contact) cc
WHERE e.id = eccr.email_id
AND eccr.table = cc.table
AND eccr.email_id = cc.id
I'm not getting the ref_id part... Is it a foreign key? Or is that the primary key for the Email_Company_Contact_Ref table?
I would think you'd want to put the reference for the Email table in the Company and Contact tables. If you need more than one emails for them, then you should create two join tables: Company_Email and Contact_Email. Your current design (with references to table names as values for a column) is bad SQL design -- just because things like RoR promote it, it won't get any better.
With proper design, the equivalent of that complicated query would look something like:
CREATE TABLE Company_Email (company_id integer, email_address varchar(100),
FOREIGN KEY company_id REFERENCES Company (id));
CREATE TABLE Contact_Email (contact_id integer, email_address varchar(100),
FOREIGN KEY contact_id REFERENCES Contact (id));
SELECT email_address, 'Company' AS kind, company_name AS name
FROM Company_Email ce JOIN Company c ON company_id = c.id
UNION
SELECT email_address, 'Contact', contact_name
FROM Contact_Email ce JOIN Contact c ON contact_id = c.id;
If you can't change it, you'll have to do the UNION along the lines Barmar explained it.
Or, you can do a SELECT DISTINCT to get rid of the duplicates from your left joined query.

How to JOIN two FKs from a table to another table?

I have a table of many-to-many relationships as:
Table relationship:
relationship_id,
first_user REFERENCES users(user_id),
second_user REFERENCES users(user_id),
Table users:
user_id,
other user information
To read friends of a given user (which can be in first_user or second_user), I need to JOIN two tables (relationships and users), but two columns of the table relationships are FK
Question 1: How can I JOIN two tables to use both FKs?
I have a table for pending requests which is similar to the table relationships. Upon approving a request, it will be deleted from requests and INSERTed into relationships.
Question 2: How can I JOIN three tables to retrieve connection and pending requests in one query.
You will have to give the instances of the "users" table aliases, so you can refer to them serparately:
SELECT u1.*, u2.* FROM relationship r
JOIN users u1 ON (u1.user_id = r.first_user)
JOIN users u2 ON (u2.user_id = r.second_user)
To select both from requests and relationships, you can use a UNION:
SELECT u1.*, u2.* FROM relationship r
JOIN users u1 ON (u1.user_id = r.first_user)
JOIN users u2 ON (u2.user_id = r.second_user)
UNION
SELECT u1.*, u2.* FROM requests r
JOIN users u1 ON (u1.user_id = r.first_user)
JOIN users u2 ON (u2.user_id = r.second_user)
To use both foreign keys, you need two joins (one for each):
select *
from relationship r
inner join users u1 on (u1.user_id = r.first_user)
inner join users u2 on (u2.user_id = r.second_user)
The {relationship_id, first_user, second_user} table contains a repeating group.
Just remove one of them (that makes relationship_id non-unique) and add a surrogate key (or add userid to the primary key).
CREATE TABLE relationships
( id INTEGER NOT NULL PRIMARY KEY
, relationship_id INTEGER NOT NULL
, user_id INTEGER NOT NULL REFERENCES users(user_id)
);
It would be a nice homework assignment to try to generate constraints for this construct.
Another way (for binary relations like marriages) is to put the "significant Other" link in the users table:
CREATE TABLE lusers
( luser_id INTEGER NOT NULL PRIMARY KEY
, magnificent_other INTEGER REFERENCES lusers (luser_id)
...
);
As a side effect, this will also make bigamy impossible.
Again: nice homework assignment to implement the constraints.