How to distinguish these two ID requests when joining tables? - sql

SQL noob here. I have a database of soccer matches that I am trying to learn/practice SQL with.
In one table (called "Match") there is the match_api_id, date, home_team_api_id, away_team_api_id, home_team_goal, away_team_goal.
In another table (called "Team") there is the team_api_id, team_long_name.
Right now I am trying to do a query to show the ID of the match, the date, the home team's name, and the away team's name.
SELECT M.match_api_id, M.date, T.team_long_name, T.team_long_name
FROM Match M
JOIN Team T ON (M.home_team_api_id = T.team_api_id)
JOIN Team T ON (M.away_team_api_id = T.team_api_id)
LIMIT 10
This code worked when I only used one join (the first one) to show the home team's name. However, when I add the second join it gives me the ambiguous column name error. How do I alter this code so that I can also display the away team's name?

YOu need different table aliases. Otherwise T is ambiguous:
SELECT M.match_api_id, M.date, TH.team_long_name, TA.team_long_name
FROM Match M JOIN
Team TH
ON M.home_team_api_id = TH.team_api_id JOIN
Team TA
ON M.away_team_api_id = TA.team_api_id;
LIMIT 10

Related

How to get the values of two foreign key columns when they correspond to the same key?

I need help in SQL , regarding this database https://www.kaggle.com/hugomathien/soccer.
I need an SQL statement that gives a table of the home team name and the away team name for a random game ( I chose Match.match_api_id = 492476)
If i run this :
SELECT Team.team_long_name , Match.home_team_api_id
FROM Team JOIN Match
ON Match.away_team_api_id = Team.team_api_id
WHERE Match.match_api_id = 492476;
I get the away team name , but not the home team name (instead I get the value of Match.home_team_api_id , as expected).
If I run :
SELECT Team.team_long_name , Match.away_team_api_id
FROM Team JOIN Match
ON Match.home_team_api_id = Team.team_api_id
WHERE Match.match_api_id = 492476;
I get the home team name , but not the away team name (instead I get the value of Match.away_team_api_id , as expected).
The problem is that both of the foreign keys Match.home_team_api_id and Match.away_team_api_id corespond to : Team.team_api_id , so when I get one I "lose" the other.
Is there an SQL statement to get both the home team name and the away team name of random match in the same table?
First, if the selection criteria is solely about the Match table, it should be the first table you mention.
Second, you're allowed to use JOIN (or INNER JOIN as it's more often written) more than once.
SELECT T1.team_long_name as Away_team_long_name,
T2.team_long_name as Home_team_long_name
FROM Match
INNER JOIN Team as T1
ON Match.away_team_api_id = T1.team_api_id
INNER JOIN Team as T2
ON Match.home_team_api_id = T2.team_api_id
WHERE Match.match_api_id = 492476;
Rephrasing this as a human procedure:
Use the match_api_id to look up the Match row in the Match table.
Take the away_team_api_id from the Match row and use it to look up a Team in the Team table. Report the team_long_name of that Team as the Away team long name.
Take the home_team_api_id from the Match row and use it to look up a Team in the Team table. Report the team_long_name of that Team as the Home team long name.
You can join the Team table twice, once for the away team and once for the home team. The aliases for the tables help track which is which. Something like:
SELECT
hometeam.team_long_name homename,
Match.home_team_api_id,
awayteam.team_long_name awayname,
Match.away_team_api_id
FROM Match INNER JOIN Team hometeam
ON Match.home_team_api_id = hometeam.team_api_id
INNER JOIN Team awayteam
ON Match.away_team_api_id = awayteam.team_api_id
WHERE Match.match_api_id = 492476

Query SQL Database for Home and Away team based on Team ID

I'm working on setting up a Football (Soccer) betting database using data from Betfair. This is my first ever Database and I'm working in MS SQL Server 2012.
I have set up 4 tables: Match, Team, Competition & Data.
My Match table contains columns: MatchID(PK), CompetitionID(FK), DateKickOff, TimeKickOff, TeamIDHome(FK), TeamIDAway(FK), ScoreHome, ScoreAway
My Team table contains columns: TeamID(PK), TeamName
I have been trying out some queries at this stage so that I can have a think about whether my tables are Normalised correctly. I wanted to run a query that would return 4 columns: Home Team Name, Home Score, Away Score, Away Team Name.
If I run this I get the first 3 columns back:
SELECT TeamName TeamH, ScoreHome, ScoreAway
FROM Match AS t
INNER JOIN Team AS n
ON t.TeamIDHome = n.TeamID
If I run this I get my fourth column:
SELECT TeamName TeamA
FROM Match AS t
INNER JOIN Team AS n
ON t.TeamIDAway = n.TeamID
But I cannot Union the 2 functions as I get an error: All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.
I believe that the error is caused because it tries to add the Away Team Names to the same column as the home team names. Can anybody suggest how I can query this correctly or let me know if I have a bad database design? Thanks
You don't need two queries for this. Add another join to Team linking the Match.TeamIdAway with team.TeamId. Like:
select HomeTeam.TeamName as TeamH, AwayTeam.Teamname as TeamA, M.ScoreHome, M.ScoreAway
from Match as M
join Team as HomeTeam on M.TeamIdHome = HomeTeam.TeamId
join Team as AwayTeam on M.TeamIdAway = AwayTeam.TeamId

Needing 2 different ID's from the same ID Table

I am pulling reports for my company and am needing to pull a specific report that I am having trouble with. We are using SQL Server 2012 and I am pulling the SQL reports.
What I need is to pull a simple report:
Group Name, List of Members in the group; Supervisor of the group.
However, the problem is that the supervisor as well as the members and the group name all come from one table in order to get the relevant information. Currently here is my SQL code below:
Use DATABASE
go
-- This is the select portion deciding the columns needed.
select
C.group_name
,C2.first_name
,C2.last_name
-- These are the tables that the query is pulling from.
FROM db..groups AS G
LEFT OUTER JOIN db..contact AS C
ON G.group_id=C.contact_id
INNER JOIN db..contact AS C2
ON G.member=C2.contact_id
go
This pulls the first portion:
The group name, then the first name of a member in that group, and then the last name of a member in that group.
However, I am having trouble getting the supervisor portion. This portion uses the table db.contact under the column supervisor_id as a foreign key. The supervisor_id uses the same unique id as the normal contact_id, but in the same table. Some contact_ids have supervisor_id's that are other contact_id's from the same table, hence the foreign key.
How can I make it so I can get the contact_id that is equal to the supervisor_id of the contact_id that is equal to the group_id?
Taking a quick stab at this while we wait for details
You know you need groups and I'm assuming you don't care about Groups that have no members. Thus Groups INNER JOINed to Contact. This generates your direct group membership. To get the supervisor, you then need to factor in the Supervisor on the specific Contact row.
You might not have a boss, or your boss might be yourself. It's always interesting to see how various HR systems record this. In my example, I'm assuming the head reports to no one instead of themselves.
SELECT
G.group_name
, C.first_name
, C.last_name
-- this may produce nulls depending on outer vs inner join below
, CS.first_name AS supervisor_first_name
, CS.last_name AS supervisor_last_name
FROM
dbo.Groups AS G
INNER JOIN
dbo.Contact AS C
ON C.contact_id = G.member
LEFT OUTER JOIN
dbo.Contact AS CS
ON CS.contact_id = C.supervisor_id;
Depending on how exactly you wanted that data reported, there are various tricks we could use to report that data. In particular, GROUPING SETS might come in handy.
SQLFiddle

How to use the result from a second select in my first select

I am trying to use a second SELECT to get some ID, then use that ID in a second SELECT and I have no idea how.
SELECT Employee.Name
FROM Emplyee, Employment
WHERE x = Employment.DistributionID
(SELECT Distribution.DistributionID FROM Distribution
WHERE Distribution.Location = 'California') AS x
This post got long, but here is a short "tip"
While the syntax of my select is bad, the logic is not. I need that "x" somehow. Thus the second select is the most important. Then I have to use that "x" within the first select. I just don't know how
/Tip
This is the only thing I could imagine, I'm very new at Sql, I think I need a book before practicing, but now that I've started I'd like to finish my small program.
EDIT:
Ok I looked up joins, still don't get it
SELECT Employee.Name
FROM Emplyee, Employment
WHERE x = Employment.DistributionID
LEFT JOIN Distribution ON
(SELECT Distribution.DistributionID FROM Distribution
WHERE Distribution.Location = 'California') AS x
Get error msg at AS and Left
I use name to find ID from upper red, I use the ID I find FROM upper red in lower table. Then I match the ID I find with Green. I use Green ID to find corresponding Name
I have California as output data from C#. I want to use California to find the DistributionID. I use the DistributionID to find the EmployeeID. I use EmployeeID to find Name
My logic:
Parameter: Distribution.Name (from C#)
Find DistributionID that has Distribution.Name
Look in Employment WHERE given DistributionID
reveals Employees that I am looking for (BY ID)
Use that ID to find Name
return Name
Tables:
NOTE: In this example picture the Employee repeats because of the select, they are in fact singular
In "Locatie" (middle table) is Location, I get location (again) from C#, I use California as an example. I need to find the ID first and foremost!
Sory they are not in english, but here are the create tables:
Try this:
SELECT angajati.Nume
FROM angajati
JOIN angajari ON angajati.AngajatID = angajari.AngajatID
JOIN distribuire ON angajari.distribuireid = distribuire.distribuireid
WHERE distribuire.locatie = 'california'
As you have a table mapping employees to their distribution locations, you just need to join that one in the middle to create the mapping. You can use variables if you like for the WHERE clause so that you can call this as a stored procedure or whatever you need from the output of your C# code.
Try this solution:
DECLARE #pLocatie VARCHAR(40)='Alba'; -- p=parameter
SELECT a.AngajatID, a.Nume
FROM Angajati a
JOIN Angajari j ON a.AngajatID=j.AngajatID
JOIN Distribuire d ON j.DistribuireID=d.DistribuireID
WHERE d.Locatie=#pLocatie
You should add an unique key on Angajari table (Employment) thus:
ALTER TABLE Angajari
ADD CONSTRAINT IUN_Angajari_AngajatID_DistribuireID UNIQUE (AngajatUD, DistribuireID);
This will prevent duplicated (AngajatID, DistribuireID).
I don't know how you are connecting Emplyee(sic?) and Employment, but you want to use a join to connect two tables and in the join specify how the tables are related. Joins usually look best when they have aliases so you don't have to repeat the entire table name. The following query will get you all the information from both Employment and Distribution tables where the distribution location is equal to california. You can join employee to employment to get name as well.
SELECT *
FROM Employment e
JOIN Distribution d on d.DistributionID = e.DistributionID
WHERE d.Location = 'California'
This will return the contents of both tables. To select particular records use the alias.[Col_Name] separated by a comma in the select statement, like d.DistributionID to return the DistributionID from the Distribution Table

TSQL INNER JOIN

I'm building an IT support ticketing portal for a multi-site company.
I cant get my head around JOIN, INNER JOIN, ON , etc.
I have 3 tables:
Firstly Support_Ticket containing Site_ID, which I already have from a previous query.
So I have the Site_ID, and need to get the name (string) of the engineer that is responsible for support on that site. Lets say Hull is Site_ID:1.
The other 2 tables :
Site_Details: containing (among others) Site_ID and Site_Default_Engineer_ID.
Engineers: containing (among others) [Engineer_ID] and Engineer_Display_Name.
What I want to achieve is (pseudo-code!):
return [Engineers].[Engineer_Display_Name]
where
[Engineers].[Engineer_ID] = [Site_Details].[Site_Default_Engineer_ID]
(but first) return [Site_Details].[Site_Default_Engineer_ID] where
[Site_Details].[Site_ID] = [Support_Ticket].[Site_ID]
if that makes sense?!
This query should work:
SELECT support_ticket.something, engineers.engineer_display_name
FROM support_ticket
JOIN site_details ON ( site_details.site_id = support_ticket.site_id )
JOIN engineers ON ( engineers.engineer_id = site_details.site_default_engineer_id )
It will present all tickets and their default engineer. Add a WHERE-clause to filter the ticket(s) you want to display.
BTW: There is no difference between JOIN and INNER JOIN.