MySQL JOIN multiple columns with corresponding ID - mysql

I have two tables, one with names of teams, the other holds various selections made by users, each of which is represented by the team's team_id. I want to be able to display the actual team names for each, but can't figure out how the join would work.
Table 1
user_id(int), selection1(int), selection2(int), selection3(int)
Table 2
team_id(int), team_name(varchar)

You need three joins:
select u.user_id, t1.team_name as team_name1, t2.team_name as team_name2,
t3.team_name as team_name3
from users u left outer join
teams t1
on u.selection1 = t1.team_id left outer join
teams t2
on u.selection2 = t2.team_id left outer join
teams t3
on u.selection3 = t3.team_id;

Related

SQL Left Join a Table on a Left Joined Table

Iam currently trying to left join a table on a left joined table as follows.
I have the tables:
accounts (id, vorname, nachname)
projektkurse (id, accounts_id, projektwochen_id)
projektkurs_einzel (id, projektkurse_id)
projektkurs_einzel_zeiten (id, date, shift, projektkurs_einzel_id)
Now I want to get every account and the amount times they have an entry inside of projektkurs_einzel_zeiten, which should also be unique. So having the same date and shift multiple times does not count as multiple entries. The result should also be limited by the column projektwochen_id from the table projektkurse. This column should match a certain value for example 8.
Some Accounts don't have any entries in projektkurse, projektkurs_einzel and projektkurs_einzel_zeiten, this is why my first thought was using LEFT JOIN like this:
SELECT accounts.id, accounts.vorname, accounts.nachname, COUNT(DISTINCT projektkurs_einzel_zeiten.date, projektkurs_einzel_zeiten.shift) AS T
FROM accounts
LEFT JOIN projektkurse on accounts.id = projektkurse.creator_id
LEFT JOIN projektkurs_einzel on projektkurse.id = projektkurs_einzel.projektkurs_id
LEFT JOIN projektkurs_einzel_zeiten ON projektkurs_einzel.id = projektkurs_einzel_zeiten.projektkurs_einzel_id
WHERE projektkurse.projektwochen_id = 8
GROUP BY accounts.id
This query does not achieve exactly what I want. It only returns accounts that have atleast one entry in projektkurse even if they have none in projektkurs_einzel and projektkurs_einzel_zeiten. The Count is obviously 0 for them but the accounts that have no entries in projektkurse are being ignored completly.
How can I also show the accounts that don't have entries in any other table with the Count 0 aswell?
I would recommend writing the query like this:
SELECT a.id, a.vorname, a.nachname,
COUNT(DISTINCT pez.date, pez.shift) AS T
FROM accounts a LEFT JOIN
projektkurse
ON a.id = pk.creator_id AND
pk.projektwochen_id = 8 LEFT JOIN
projektkurs_einzel pe
ON pk.id = pe.projektkurs_id LEFT JOIN
projektkurs_einzel_zeiten pez
ON pe.id = pez.projektkurs_einzel_id
GROUP BY a.id, a.vorname, a.nachname;
Notes:
Your problem is fixed by moving the WHERE condition to the ON clause. Your WHERE turns the outer join into an inner join, because NULL values do not match.
Table aliases make the query easier to write and to read.
It is a best practice to include all unaggregated columns in the GROUP BY. However, assuming that id is unique, your formulation is okay (due to something called "functional dependencies").
You should not use eft join table's column ins where condition this work as inner join
You should move the where condition for a left joined table in the corresponding ON clause
SELECT accounts.id, accounts.vorname, accounts.nachname, COUNT(DISTINCT projektkurs_einzel_zeiten.date, projektkurs_einzel_zeiten.shift) AS T
FROM accounts
LEFT JOIN projektkurse on accounts.id = projektkurse.creator_id
AND projektkurse.projektwochen_id = 8
LEFT JOIN projektkurs_einzel on projektkurse.id = projektkurs_einzel.projektkurs_id
LEFT JOIN projektkurs_einzel_zeiten ON projektkurs_einzel.id = projektkurs_einzel_zeiten.projektkurs_einzel_id
GROUP BY accounts.id

sql join returns me two same values

I have two tables in mysql: matches and teams, matches have columns home_team and away_team which are connected with fk in table teams.team_id.. I want to get those names in home_team and away_team instead their id ...
I've tried this, but it returns me same value two times.. I'm doing something wrong but I can't figure it out.
Code
SELECT matches.home_team, matches.away_team, teams.name as home, teams.name as
away FROM matches left join teams ON matches.home_team = teams.team_id
left join teams as t ON matches.away_team = t.team_id
First value is correct, but second one no.
Your aliases are off. You are referring to the same first teams table twice in your current query. Try this version, which distinguishes the two joined teams table using proper aliases.
SELECT
m.home_team,
m.away_team,
t1.name AS home,
t2.name AS away
FROM matches m
LEFT JOIN teams t1
ON m.home_team = t1.team_id
LEFT JOIN teams t2
ON m.away_team = t2.team_id;

Display name of foreign key column instead of its id

I have a match table whose structure is displayed here
in this table i have column teama, teamb which are a foreign key columns referenced to team table's t_id. Basically, what i want to do is that when i select all data from this table i want it to display the values in teama, and teamb instead of their t_id. Structure of Team table is here
Query which i am writing is below:
select *
from teams,matches
where
matches.team_a=teams.t_id
and matches.team_b=teams.t_id;
You need to join 2 columns of matches to the teams table:
select
m.m_id,
t1.t_name as team_a,
t2.t_name as team_b,
m.m_time
from
matches m inner join teams as t1 on m.team_a=t1.t_id
inner join teams as t2 on m.team_b=t2.t_id
order by m.m_id;
First, never use commas in the FROM clause. Always use proper, explicit, standard JOIN syntax. You need two JOINs in fact:
select m.*, ta.t_name as name_a, tb.t_name as name_b
from matches m left join
teams ta
on m.team_a = ta.t_id left join
teams tb
on m.team_b = tb.t_id;
This uses left join just to ensure that you get all matches, even if one of the teams is missing. In this case, that is probably not an important consideration, so inner join would be equivalent.
You want two INNER JOINs from table matches to table teams, like :
SELECT
ta.t_name,
tb.t_name
FROM
matches m
INNER JOIN team as ta on ta.t_id = matches.team_a
INNER JOIN team as tb on tb.t_id = matches.team_b
You can create view after join it was make your work simple for further developement,i was improove mr.forbas code as follow
CREATE VIEW team AS select
m.m_id,
t1.t_name as team_a,
t2.t_name as team_b,
m.m_time
from
matches m inner join teams as t1 on m.team_a=t1.t_id
inner join teams as t2 on m.team_b=t2.t_id
order by m.m_id;

Combination of table left join to an inner join in mysql

I have 3 tables, cars, cars_owner and owner.
I want to have the complete list of cars, those that do have owners and those that don't.
When a car has an owner, I must have the data of the owner.
Wrong query 1 (selects ownerless cars out):
SELECT * FROM car
LEFT JOIN cars_owner ON ...
INNER JOIN owner ON ...
Wrong query 2 (selects cars_owner relations without owners too):
SELECT * FROM car
LEFT JOIN cars_owner ON ...
LEFT JOIN owner ON ...
How do I left join a table with an inner join in MySQL?
This Query returns the cars that have owners:
SELECT * FROM car
LEFT JOIN cars_owner ON (car.CarID=cars_owner.CarID)
inner join owner ON (owner.OwnID = cars_owner.OwnID)
However this returns the cars without owners:
SELECT * FROM car
where (car.CarID!=(SELECT car.CarID FROM car
LEFT JOIN cars_owner ON (car.CarID=cars_owner.CarID)
inner join owner ON (owner.OwnID = cars_owner.OwnID)) )
You just need to nest the JOINs correctly:
SELECT * FROM car
LEFT JOIN (cars_owner INNER JOIN owner ON cars_owner.owner_id = owner.owner_id
) ON car.car_id = cars_owner.car_id
The point is that you want all cars (so a left join on cars_owner), but only cars_owner that have an existing owner (so an inner join on owner).
The brackets make sure that the inner join is executed first. That is: Give me all cars, and from those car_owners that have an actual owner, show the owners (otherwise show them as NULL, but don't discard the whole car row).

Left outer join to a generated table?

Am I on completely the wrong tack ?
I want to do a left outer join to a query generated from 2 tables , but i keep getting errors. Do I need a different approach?
t1:
ID, Surname,Firstname
t2:
ID,JobNo,Confirmed
I have the following query:
SELECT JobNo AS N, StaffID AS P, Confirmed as C,
FirstName AS F,Surname AS S
FROM gigs_players, Players
WHERE t1.StaffID=t2.StaffID AND JobNo="2"
AND (`Confirmed` IS NULL OR Confirmed ='Y' )
ORDER BY Instrument,Surname
I want to add:
LEFT OUTER JOIN contacted (ON t1.StaffID=contact.ID AND t2.JobNo=contact.JobNo)"
Can I do a left outer join to a query generated from 2 tables ?
In order to use the t1 and t2 in the left outer join that you want to add you need to join them with the first tables, you can't reference them directly in the left outer join you, Something like the following:
SELECT JobNo AS N, StaffID AS P, Confirmed as C,
FirstName AS F,Surname AS S
FROM gigs_players, Players
Inner join t1 on ...
Inner join t2 on ...
LEFT OUTER JOIN contacted c
on t1.StaffID=c.ID AND t2.JobNo = c.JobNo
WHERE t1.StaffID=t2.StaffID AND JobNo="2"
AND (`Confirmed` IS NULL OR Confirmed ='Y' )
ORDER BY Instrument,Surname
So, based in your tables' structure, define the conditions of the two joins with t1 and t2 with other tables.
Here is the an example of a left join to a sub query. This might be what you are looking for.
select
parts.id,
min(inv2.id) as nextFIFOitemid
from test.parts
left join
( select
inventory.id,
coalesce(parts.id, 1) as partid
from test.inventory
left join test.parts
on (parts.id = inventory.partid)
) inv2
on (parts.id = inv2.partid)
group by parts.id;