I have 3 tables that reference each other.. Leagues, Teams, and Players.
Leagues have leagueid, leaguename, city
Teams have teamid, teamname, numberofplayers, leagueid(fk)
Players have playerid, playername, position, teamid(fk)
How can I display a table such as Players to show all of the contents and using the teamid foreign key, display their team name instead of that column?
SELECT Players.*, teamname
FROM Players JOIN Teams USING (teamid)
You just need to join on the teamid column that matches between the two tables.
You need to join both tables use INNER JOIN.
SELECT a.*, b.*
FROM Players a
INNER JOIN Teams b
ON a.teamid = b.teamid
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
By using inner join
SELECT b.teamname,a.playername, a.position
FROM Players a
INNER JOIN Teams b
ON a.teamid = b.teamid
If you are specifying the league,
SELECT c.leaguename, c.city ,d.* FROM
(SELECT b.teamname,a.playername, a.position
FROM Players a
INNER JOIN Teams b
ON a.teamid = b.teamid) d
INNER JOIN Leagues c
ON d.leagueid= c.leagueid
Related
I have three MySQL tables; "teams" and two tables depending on team type ("team_type_1" and "team_type_2"). I'm needing to query all three tables into one table, and sum each team's miles from both of the team_type tables into one "miles" column.
My queries below work as needed but since my JOIN queries aren't using primary IDs it either locks up or takes too long.
Would be nice to use the primary IDs "team_type_1.id" and "team_type_2.id" in the JOINs but my try in the last query below is still using non-primary keys in the inner queries. Is there a different approach I could take to speed up the query?
Table 1: teams (3000 total records)
id (primary) | team_name
Table 2: team_type_1 (12000 total records)
id (primary) | team_id | miles
Table 3: team_type_2 (150000 total records)
id (primary) | team_id | miles
Combine the above tables into:
team_name | miles
When running these queries separately using primary keys it only takes milliseconds, but I need these tables combined:
SELECT
teams.team_name,
SUM(team_type_1.miles)
FROM team_type_1
LEFT JOIN teams ON teams.id = team_type_1.team_id
GROUP BY team_type_1.team_id
SELECT
teams.team_name,
SUM(team_type_2.miles)
FROM team_type_2
LEFT JOIN teams ON teams.id = team_type_2.team_id
GROUP BY team_type_2.team_id
When combining, and not using primary keys, it locks up the database:
SELECT
teams.team_name,
SUM(CASE WHEN team_type_2.miles THEN team_type_2.miles ELSE team_type_1.miles END)
FROM teams
LEFT JOIN team_type_1 ON team_type_1.team_id = teams.id
LEFT JOIN team_type_2 ON team_type_2.team_id = teams.id
GROUP BY teams.id
This takes around 8-10 seconds to run but the inner select is using non-primary IDs; is there a way to speed this up?
SELECT
teams.team_name,
SUM(CASE WHEN team_type_2.miles THEN team_type_2.miles ELSE team_type_1.miles END)
FROM teams
LEFT JOIN team_type_1 ON team_type_1.id = (SELECT team_type_1.id FROM team_type_1 WHERE team_type_1.team_id = teams.id GROUP BY team_type_1.team_id)
LEFT JOIN team_type_2 ON team_type_2.id = (SELECT team_type_2.id FROM team_type_2 WHERE team_type_2.team_id = teams.id GROUP BY team_type_2.team_id)
WHERE team_type_2.miles > 0 OR team_type_1.miles > 0 GROUP BY teams.id
UPDATE:
Thanks #Strawberry for the UNION hint, in addition the the few columns and three tables above, I also had other tables and columns I'm querying, but didn't mention those since I'm able to use the primary IDs for those. Below is my full query structure, using UNIONS, and it is working as I needed.
SELECT
teams.team_name,
teams.start_date,
team_counties.county_name,
team_leagues.league_name,
SUM(team_type_1.miles)
FROM team_type_1
LEFT JOIN teams ON teams.id = team_type_1.team_id
LEFT JOIN team_counties ON team_counties.id = teams.county_id
LEFT JOIN team_leagues ON team_leagues.id = teams.league_id
GROUP BY team_type_1.team_id
UNION
SELECT
teams.team_name,
teams.start_date,
team_counties.county_name,
team_leagues.league_name,
SUM(team_type_2.miles)
FROM team_type_2
LEFT JOIN teams ON teams.id = team_type_2.team_id
LEFT JOIN team_counties ON team_counties.id = teams.county_id
LEFT JOIN team_leagues ON team_leagues.id = teams.league_id
GROUP BY team_type_2.team_id
There are a few ways around this, but the easiest solution is to simply index the team_id column in the two sub-tables:
ALTER TABLE `team_type_1`
ADD INDEX `team_id` (`team_id`);
ALTER TABLE `team_type_2`
ADD INDEX `team_id` (`team_id`);
This should allow you to do the following with some speed:
SELECT teams.id,
teams.team_name,
SUM(IFNULL(team_type_1.miles, 0) + IFNULL(team_type_2.miles, 0)) sum_miles
FROM teams
LEFT JOIN team_type_1 ON team_type_1.team_id = teams.id
LEFT JOIN team_type_2 ON team_type_2.team_id = teams.id
GROUP BY teams.id,
teams.team_name
I had the same issue. In my case, I changed the column (not primary) from non-unique index to unique index. It sped up my query by 3x. Hope, it helps someone.
I have fours tables and I wanted to join all three tables with the one table.
I have listed my problem as follows:
Tables:
users
user_training
user_courses
user_certificates
I wanted to get the data from [2,3,4] tables that user_id field matches with the users table ID field.
When I try the INNER JOIN it gives me the result for users that are common in all the tables, But I just wanted to check the [2,3,4] tables with the table [1] Records.
My Query...
SELECT A.training_name AS 'training_name', C.course_name AS 'course_name', D.certificate_name AS 'certificate_name'
FROM user_training AS A INNER JOIN users AS B ON A.user_id=B.ID INNER JOIN user_courses AS C ON B.ID = C.user_id INNER JOIN user_certificates AS D ON B.ID = D.user_id;
Thanks in Advance.
use left join
select u.* from users u
left join user_training ut on ut.user_id=u.user_id
left join user_courses uc on uc.user_id=u.user_id
left join user_certificates uct on uct.user_id=u.user_id
With this one you are getting all users and their respective trainings:
SELECT *
FROM `users`
LEFT JOIN `user_training` ON `users`.`id` = `user_training`.`user_id`
Changing *_trainig to *_courses or *_certificates will return all users with respected courses or certificates.
If you need to get data in one query, try this one:
SELECT *
FROM `users`
LEFT JOIN `user_training` ON `users`.`id` = `user_training`.`user_id`
LEFT JOIN `user_courses` ON `users`.`id` = `user_courses`.`user_id`
LEFT JOIN `user_certificates` ON `users`.`id` = `user_certificates`.`user_id`
If user has no trainings, courses, certificates all remaining fields will be null-ed.
I have normalized tables I want to select the items that belong to the userid
I'm familiar with select syntax but I'm very weak in joins tables so I'm a bit confused on how to get the items that belong to the user should I use join ? or is there other way
this is just simple example of my tables they have more fields
..........
user
..........
userid
firstname
address
..........
items
..........
itemsid
itemName
itemDescription
..........
user_items
..........
userid(FK)
itemsid(FK)
Use two inner join
select a.*, b.*
from user_items as c
inner join user as a on a.userid = c.userid
inner join items as b on b.itemsid = c.itemsid;
Use INNER JOIN
SQL
select user.*, items.*
from user_items
inner join user on user.userid = items.userid
inner join items on items.itemsid = user_items.itemsid;
So if I read this correctly, user_items.userid = user.userid.
So you want to join, something like this.
SELECT i.itemsid, i.itemName, i.Description FROM items i JOIN users us ON ui.userid = us.userid JOIN user_items ui ON ui.itemsid = i.itemsid WHERE ui.userid = VALUE;
Replace Value with your actuall user id
In a table if I have:
FixtureID, HomeTeam, AwayTeam
Can I replace the ID that is related to HomeTeam and AwayTeam when it displays in the browser? HomeTeam and AwayTeam are both related to TeamID in the Teams table.
I want to show all fixtures and then replace both "TeamID" with "TeamName" so the name shows up instead of the ID?
So far I have:
$sql = <<<SQL
SELECT fix.*, tea.*
FROM Fixtures fix
INNER JOIN Teams tea USING (TeamID)
SQL;
Then
echo '<p>Fixtures</p>';
echo '<div>'.$row['HomeTeam'].' v '.$row['AwayTeam'].'</div>';
EDIT:
Ok so I found a post that was similar to what I need and have tried the following:
$sql = <<<SQL
SELECT fix.*, tea1.*, tea2.*
FROM Fixtures fix
INNER JOIN Teams tea1 ON fix.HomeTeam = tea1.TeamID
INNER JOIN Teams tea2 ON fix.AwayTeam = tea2.TeamID
SQL;
However it's still just showing the team ID's rather than the names from the Teams table.
Solved it myself
$sql = <<<SQL
SELECT f.*, t1.TeamName 'HomeTeam', t2.TeamName 'AwayTeam'
FROM Fixtures f
INNER JOIN Teams t1 ON f.HomeTeam = t1.TeamID
INNER JOIN Teams t2 ON f.AwayTeam = t2.TeamID
SQL;
I have a MYSQL query who have to list all post i want it to post. But it dont do it. It shows posts when i have more then one post in the table "meaOrder" with the same "ordCode". But when i have only on post in meaOrder, i don't show it. What can i do?
SELECT koden, wish, rnamn, bild, pris, cname, onsktext
FROM (
SELECT m.wishText as onsktext, m.meaOID as midn, m.ordcode as koden, w.wish as wish, r.meaName as rnamn, r.meaImg as bild,
r.meaPrice as pris, k.catName as cname from cats k, meals r, wishes w,
meaOrder m
join orders c on c.ordNR=4401
WHERE c.ordStatus=1 AND m.ordNR=c.ordNR AND m.meaID=r.meaID AND m.wishesID=w.id
AND r.catID=k.catID
) T
GROUP BY koden, rnamn, bild, pris, cname
ORDER BY midn DESC
TABLE orders
http://grab.by/m74E
TABLE meaOrder http://grab.by/m74Q
Try replacing the JOIN with RIGHT JOIN in this case. The difference is explained at JOIN Syntax page in MySQL docs . In short - JOIN returns row only if there are corresponding rows in both joined tables (inner join). LEFT JOIN / RIGHT JOIN return all rows from one of the tables and corresponding row if it exists from the other table (those are outer joins)
Do you need a subselect?
This seems to cover it:-
SELECT m.ordcode AS koden, w.wish AS wish, r.meaName AS rnamn, r.meaImg AS bild, r.meaPrice AS pris, k.catName AS cname, m.wishText AS onsktext
FROM cats k
INNER JOIN meals r ON r.catID = k.catID
INNER JOIN meaOrder m ON m.meaID = r.meaID
INNER JOIN wishes w ON m.wishesID = w.id
INNER JOIN orders c ON m.ordNR = c.ordNR
WHERE c.ordStatus = 1
AND c.ordNR = 4401
GROUP BY m.ordcode, r.meaName, r.meaImg, r.meaPrice, k.catName
ORDER BY midn DESC