Multiple MySQL selects - mysql

I have a query but I want to add another field to it from another table...
This is what I am using now:
SELECT *
FROM tournaments t , tournament_participants t1
WHERE t.tournament_id = t1.tournament_id
ORDER BY t1.tournament_id, t1.team_id;
This works fine, but I also want to get the team name from the team table using the team_id as part of this query...
I have no idea how to do this, can anyone help?

Simply using joins:
SELECT * FROM tournaments AS t
LEFT JOIN tournament_partecipants AS tp ON t.tournament_id = tp.tournament_id
LEFT JOIN team ON tp.team_id = team.team_id
ORDER BY tp.tournament_id, tp.team_id

I have no idea what sort of table schema you have. Following query is based on lots of assumptions. So I may be wrong to what you really need. Please take a look at it.
Query:
select p.pid, p.pname, t.id as teamID
from participants p
left join tournament tt
on p.ttnid = tt.tnid
inner join team t
on tt.tnid = t.ttid
Results:
PID PNAME TEAMID
1 john 10
2 tim 10
3 alex 20
4 ron 20
5 kate 30
Reference: SQLFIDDLE
Please let us know if you require any different solution or further clarification :)

Try This:
SELECT t.*, t1.*, t2.name
FROM tournaments t
INNER JOIN tournament_participants t1 ON t.tournament_id = t1.tournament_id
INNER JOIN teams t2 ON t1.team_id = t2.team_id
ORDER BY t1.tournament_id, t1.team_id;

Related

Remove duplicates based on rank after join in SQL request

I am using MySQL 5.6.
I have a SQL table with a list of users:
id name
1 Alice
2 Bob
3 John
and a SQL table with the list of gifts for each user (numbered in order of preference):
id gift rank
1 balloon 2
1 shoes 1
1 seeds 3
1  video-game 1
2 computer 2
3 shoes 2
3 hat 1
And I would like a list of the preferred gift for each user (the highest rank - if two gifts have the same rank, pick only one randomly) (bonus: if the list could be randomized, that would be perfect!):
id name gift rank
2 Bob computer 2
1 Alice shoes 1
3 John hat 1
I tried to use the clause GROUP BY but without any success.
Considering rank as a part of your data; Without using window functions or complex sub queries
SELECT u.id, u.name, g.gift
FROM users u
JOIN gifts g ON g.id = u.id
LEFT JOIN gifts g2 ON g2.id = g.id AND g2.rank > g.rank
WHERE g2.id IS NULL;
Added link http://sqlfiddle.com/#!9/62f59e/15/0
You can use row_number to get one row for each User.(Mysql 8.0+)
SELECT A.ID,NAME,GIFT,`RANK` FROM USERS A
LEFT JOIN (
SELECT ID,GIFT,`RANK` FROM
(SELECT *,ROW_NUMBER() OVER(PARTITION BY ID ORDER BY `RANK` ASC) AS RN FROM X) X
WHERE RN =1
) B
ON A.ID= B.ID
I do not know DB what you use. And I'm not an expert in SQL(I can have some mistake in next). But I think it is not difficult.
So I can give you just advice that you have to think gradually. Let me write.
First All I need is the highest rank. So I have to get this.
SELECT MAX(RANK)
FROM GIFT
GROUP BY ID
And then I think that I need get gifts from this rank.
SELECT GIFT.*
FROM GIFT
INNER JOIN(
SELECT ID, MAX(RANK)
FROM GIFT
GROUP BY ID
) filter ON GIFT.ID = filter.ID AND GIFT.RANK = filter.RANK
I think this is the table what you want!
So If below code works, That's what you really want.
SELECT *
FROM USER
LEFT OUTER JOIN(
above table
) GIFT ON USER.ID = GIFT.ID
But Remember this, I said I'm not an expert in SQL. There can be better way.
Checkout the query
SELECT tbluser.id,name,gift,rank into tblrslt
FROM tbluser
LEFT JOIN tblgifts
ON tbluser.id = tblgifts.id order by id,rank;
SELECT tt.*
FROM tblrslt tt
INNER JOIN
(SELECT id, min(rank) AS rank
FROM tblrslt
GROUP BY id) groupedtt
ON tt.id = groupedtt.id
AND tt.rank = groupedtt.rank order by id
In MySQL versions older than 8 you have no ranking functions available. You'll select the minimum rank per user instead and use these ranks to select the gift rows. This means you access the gifts table twice.
I suggest this:
select *
fron users u
join gifts g
on g.id = u.id
and (g.id, g.rank) in (select id, min(rank) from gifts group by id)
order by u.id;
If you also want to show users without gifts, simply change the inner join to a left outer join.

SQL query to get records that match ALL the criteria

I need to write a SQL query to get the patients that have stayed in ALL the hospitals of the city where they live. In one city there may be several hospitals of course.
So for example, if the patient 'xxx' who lives in Washington has been in a hospital, I need to list him only if he's been in all the hospitals of Washington and no less.
This is the structure of the tables:
table patient
patientID
patientCity
table hospital
hospitalCode
hospitalCity
table hospital_stay
hospitalCode
patientID
cityStay
What's the most efficient way to do this for MySQL? Thank you!
Unfortunately, MySQL can't order before grouping, so I had to use subquery to order the result correctly before grouping it.
Have fun :)
SELECT * FROM (
SELECT
p.patientID,
hs.hospitalCode
FROM
patient p
INNER JOIN hospital h ON (p.patientCity = h.hospitalCity)
LEFT JOIN hospital_stay hs ON (p.patientID = hs.patientID AND h.hospitalCode = hs.hospitalCode)
ORDER BY 2
) AS tmp_table
GROUP BY 1
HAVING NOT ISNULL(hospitalCode)
This query should work :
Select p.patientID
, p.patientCity
from patient p
inner join hospital h on h.hospitalCity = p.patientCity
inner join hospital_stay hs on hs.hospitalCode = h.hospitalCode
--where hs.cityStay = 1
group by p.patientID, p.patientCity
having count(*) = (select count(*) from hospital
where hospitalCity = p.patientCity);
Remove the comment if cityStay is kind of a flag that says that the patient went to the hospital.

query left join or data insert?

OK - I have three tables, structured below
tbl_1
------
userid
teamid
teamname
eliminated
tbl_2
------
teamid
week
team
tbl_3
------
team
NFLname
nfl-schedule
------
week
time
awayteam (same as "team" in tbl_3)
hometeam (same as "team" in tbl_3)
This is a query on a "survivor league" where I need to get the teamid, teamname, eliminated, team, week, and NFLname for each week. If a user hasn't selected a team for this week, week 2 for instance, I want to see a blank row for that week. I"m assuming I could backfill the rows into the database for each teamid, but was wondering if I could do this simply with sql and some inner joins?
select a.teamid, a.teamname, a.eliminated, b.team, b.week, c.NFLnamefrom `tbl_1` a
left join `tbl_2` b on a.teamid = b.teamid
left join `tbl_3` c on c.`team` = b.team
where a.userid = XXX
You can use left joins for this, but you have to take care of the order you use the tables.
Another problem would be when there is a pick for this week from another user, so I think you would have to use a subquery like this:
select w.week,t.teamid,t.teamname,t.eliminated,t.team,t.NFLname
from nfl-schedule w
left join (
select a.teamid, a.teamname, a.eliminated, b.team, b.week, c.NFLname
from `tbl_1` a
left join `tbl_2` b on a.teamid = b.teamid
left join `tbl_3` c on c.`team` = b.team
where a.userid = XXX
) t on w.week = t.week

Mysql Multiple ANDS

I have three tables persons, jobs, jobs_persons
One person can have multiple jobs.
Person 1 is Technical Support AND Manager
Person 2 is Technical Support
Person 3 Is Manager
Job 1 Technical Support
Job 2 Manager
I need to find a query give me the result for the person who currently is Technical Support AND Manager
The answer would be only Person 1
SELECT persons.*
FROM persons INNER JOIN jobs_persons ON persons.id = jobs_persons.person_id
INNER JOIN jobs ON jobs.id = jobs_persons.job_id
WHERE job.id IN (1,2)
Returns 3 rows
SELECT persons.*
FROM persons INNER JOIN jobs_persons ON persons.id = jobs_persons.person_id
INNER JOIN jobs ON jobs.id = jobs_persons.job_id
WHERE job.id = 1 AND job.id = 2
Returns 0 rows.
I'm currently working on Ruby on Rails.
Somebody can help?
You want to use an OR operator. Using job.id = 1 AND job.id = 2 will only return elements where id equals 1 and at the same time 2. No element can do that. You want elemets where th id is 1 or where the id is 2.
to make it more obvious:
SELECT * FROM table WHERE lastname = 'Smith' AND firstname = 'James';
when executing this you obviously don't want everybody who is called Smith or James. ;-)
EDIT:
Misread the question. what you need is a second join to join the jobs table two times in and join them with the different jobs. It is a bit hard as you didn't show the schema, but this might work:
SELECT persons.*
FROM persons
INNER JOIN jobs_persons jp1 ON persons.id = jp1.person_id
INNER JOIN jobs_persons jp2 ON persons.id = jp2.person_id
INNER JOIN jobs j1 ON j1.id = jp1.job_id
INNER JOIN jobs j2 ON j2.id = jp2.job_id
WHERE j1.id = 1 AND j2.id = 2
Try this to get all the person who has got a job of 1 AND 2 in your associative entity table. No need to hit the job table.
SELECT p.*
FROM persons p
WHERE id in (
SELECT person_id FROM jobs_persons
WHERE job_id IN (1,2)
GROUP BY person_id
HAVING COUNT(*) = 2
);
With your recent comments, it seems you're having performance problems. That's really outside of the scope of this question and answer.
You need to make sure your indexes are in place on the appropriate columns:
jobs_person.job_id
persons.id

MYSQL Query multiple id to name resolution between two tables

I have 2 tables like this:
[games]
gameid
hometeamid
awayteamid
score
and
[teams]
teamid
teamname
How would i create a query to output something like:
[home team][away team][score]
49ers chargers 28-17
You see, i need to resolve 2 team names with 2 team ids within the same table and output just the names. Thanks in advance for your help!
SELECT
ht.TeamName AS HomeTeam,
vt.TeamName AS AwayTeam,
g.Score
FROM
games g INNER JOIN teams ht
on g.hometeamid = ht.teamid
INNER JOIN teams vt
on g.awayteamid = vt.teamid
I'd suggest naming the tables "game" and "team" - as I'm not a fan of plural table names. I'm not alone in this opinion, but it's really a style/preference thing.
This should work for you:
select t1.teamname, t2.teamname, g.score
from games as g
left outer join team as home_team
on g.hometeamid = home_team.id
left outer join team as away_team
on g.awayteamid = away_team.id
SELECT (SELECT teams.teamname FROM teams WHERE teams.teamid=games.awayteamid) AS awayteam,
(SELECT teams.teamname FROM teams WHERE teams.teamid=games.hometeamId) AS hometeam, score
FROM games
WHERE gameid = '1'