Need help with a simple Join - sql

Oi
Right to the problem.
SELECT *,t.id AS threadid FROM threads t
LEFT JOIN players p on p.id = t.last_poster
WHERE t.boardid = $boardid
I have two fields in threads called posterid and lastposterid. Which are the IDs of the thread starter / last poster. What I want to do is to get their names from players table.
But how?

You just need to join to your players table twice, like this.
SELECT
threads.*,
starterPlayer.*,
lastPosterPlayer.*
FROM
threads
LEFT OUTER JOIN
players starterPlayer
ON
starterPlayer.id = threads.posterid
LEFT OUTER JOIN
players lastPosterPlayer
ON
lastPosterPlayer.id = threads.lastposterid

You can join to the same table twice and give the table a different alias.
This presumes that there always will be a first and last poster, if this is the case then you want an INNER JOIN rather than a LEFT JOIN, you will need to change the select statement to get the relevant fields.
SELECT t.id AS threadid, playerFirst.name AS FirstPoster, playerLast.name as LastPoster
FROM threads t
INNER JOIN
players playerFirst ON playerFirst.id = t.posterid
INNER JOIN
players playerLast ON playerLast.id = t.lastposterid

How about...
SELECT *,
(SELECT name
FROM players
WHERE players.id = threads.posterid) AS poster,
(SELECT name
FROM players
WHERE players.id = threads.lastposterid) AS last_poster
FROM threads;

Related

How to find which entry has the most identical values in other columns

I need to find province that has the most cities in them.
The best solution I came up with was joining the tables together and selecting only province and type of place (I need to find city). I did it like this.
select wojewodztwo,typmsc
from wojewodztwa inner join
powiaty
on wojewodztwa.klwoj = powiaty.klwoj inner join
gminy
on powiaty.klpow = gminy.klpow inner join
miejscowosci
on gminy.klgm = miejscowosci.klgm inner join
typymsc
on miejscowosci.kltm = typymsc.kltm
Where ''wojewodztwo'' is a column of provinces and ''typmsc'' is a column of types of places
Now I need to find a way how to select province (just one) that has the most cities inside of it.
I don't know how to look for the province that has the most occurrences of city("miasto") inside of the typymsc column
to look for the province that has the most occurences of city("miasto") inside of the typymsc column
Use filtering, aggregation, order by and limit:
select wojewodztwo, count(*) as num_cities
from wojewodztwa inner join
powiaty
on wojewodztwa.klwoj = powiaty.klwoj inner join
gminy
on powiaty.klpow = gminy.klpow inner join
miejscowosci
on gminy.klgm = miejscowosci.klgm inner join
typymsc
on miejscowosci.kltm = typymsc.kltm
where typmsc = 'miasto'
group by wojewodztwo
order by count(*) desc
limit 1;

Left outer join with count, on 3 tables not returning all rows from left table

I have these 3 tables:
Areas - id, name
Persons - id, area_id
Special_Persons - id_person, date
I'd like to produce a list of all Areas, followed by a count of Special Persons in each area, including Areas with no Special Persons.
If I do a left join of Areas and Persons, like this:
select a.id as idArea, count(p.id) as count
from areas a
left join persons p on p.area_id = a.id
group by a.id;
This works just fine; Areas that have no Persons show up, and have a count of 0.
What I am not clear on is how to do the same thing with the special_persons table, which currently only has 2 entries, both in the same Area.
I have tried the following:
select a.id as idArea, count(sp.id_person) as count
from special_persons sp, areas a
left join persons p on p.area_id = a.id
where p.area_id = a.id
and sp.id_person = p.id
group by a.id;
And it only returns 1 row, with the Area that happens to have 2 Special Persons in it, and a count of 2.
To continue getting a list of all areas, do I need to use a sub-query? Another join? I'm not sure how to go about it.
You can add another left join to the Special_Persons table:
select a.id as idArea, count(p.id), count(sp.id_person)
from areas a
left join persons p on p.area_id = a.id
left join special_persons sp on sp.id_person = p.id
group by a.id;

SQL Query using multiple JOINS without sub query

Lets say I have three tables with these columns,
Players - id, name
Events - id, name
Games - first_player_id, second_player_id, event_id.
And I need the players details who are playing in a game which is happening in an event.
And I could write query like,
SELECT players.id, events.id as event_id,
(SELECT name as player_one_name from players where id = games.first_player_id),
(SELECT name as player_two_name from players where id = games.second_player_id),
games.id as game_id
FROM events
INNER JOIN games on events.id = games.event_id
INNER JOIN players on games.first_player_id = players.id;"
Here I am using two sub queries to fetch players name. And it gives correct results. Can this query be optimized? For ex, can I remove any subquery or innerjoin ?
FYI, I use PostgreSQL database.
Thanks.
If you do not want sub queries in your select statement then you must provide a join for each subset. Since your database is set oriented the two INNER JOINS would prove more efficient.
SELECT players.id, events.id as event_id,
player_one_name=player_one.name,
player_tow_name=player_two.name
FROM events
INNER JOIN games on events.id = games.event_id
INNER JOIN players player_one on games.first_player_id = player_one.id
INNER JOIN players player_two on games.second_player_id = player_two.id
You must do a join for each foreign key
SELECT players_a.id, events.id as event_id,
players_a.name as player_one_name,
players_b.name as player_two_name,
games.id as game_id
FROM events
INNER JOIN games on events.id = games.event_id
INNER JOIN players players_a on games.first_player_id = players.id
INNER JOIN players players_b on games.first_player_id = players.id
The currently accepted answer is right about joining the players table twice, but mostly wrong otherwise. This would work:
SELECT e.id AS event_id
,g.id AS game.id
,p1.name AS first_player
,p2.name AS second_player
FROM events e
LEFT JOIN games g ON g.event_id = e.id
LEFT JOIN players p1 ON p1.id = g.first_player_id
LEFT JOIN players p2 ON p2.id = g.second_player_id;
Use LEFT [OUTER] JOIN to cover the cases where an event does not have a game or a game does not have both players (yet).
Use table aliases to simplify your syntax. To join the same table twice you also need at least one table alias.
After attaching an alias to a table in the FROM list, only that alias is visible in your query, not the original name of the table.
Study the manual for details.

Select Query from 3 tables with foreign keys

I Have 3 Tables with foreign keys to each other.
I want to write a SQL Server Stored Procedure to select records from one of them.
Now, let's suppose that i want all the Winner records referring to the Player records referring to The Game with the ID=2, how can i proceed?
Thank you.
you have specified all the Winner records So that i have used the left join for player and game. But the Overall code works according to the where condition.
Try This,
select w.* from Winner w
left Join Player p on p.ID_player = w.player_FK
left join Game g on g.ID_game = p.Game_FK
where Game.ID_game = 2
You need to use a SELECT and INNER JOIN then to filter on GameID 2 you can use a WHERE clause.
SELECT ID_Winner, Name, Lastname, Player_FK
FROM Winner
INNER JOIN Player on Player.ID_Pplayer = Winner.Player_FK
INNER JOIN Game ON Game.ID_game = Player.Game_FK
WHERE Game.ID_game = 2

Left outer join and group by issue

I wrote a query. this query sum fields from 2 different table. And grouped by main table id field. But second left outer join is not grouped and giving me different results.
SELECT s.*,
f.firma_adi,
sum(sd.fiyat) AS konak,
sum(ss.fiyat) AS sponsor
FROM fuar_sozlesme1 s
INNER JOIN fuar_firma_2012 f
ON ( s.cari = f.cari )
LEFT OUTER JOIN fuar_sozlesme1_detay sd
ON ( sd.sozlesme_id = s.id )
LEFT OUTER JOIN fuar_sozlesme1_sponsor ss
ON ( ss.sozlesme_id = s.id )
GROUP BY s.id
ORDER BY s.id DESC
I know, it is really complicated but I'm stucking on this issue.
My question is: why second left outer join is not correctly sum of field . If I remove second left outer join or first, everything is normal.
The problem is that you have multiple dimensions on your data, and the number of rows is multiplying beyond what you expect. I would suggest that you run the query for one id, without the group by, to see what rows the join is producing.
One way to fix this is by using correlated subqueries:
select s.*, f.firma_adi,
(select SUM(sd.fiyat)
from fuar_sozlesme1_detay fd
where sd.sozlesme_id = s.id
) as konak,
(select SUM(ss.fiyat)
from fuar_sozlesme1_sponsor ss
where (ss.sozlesme_id = s.id)
) as sponsor
from fuar_sozlesme1 s inner join
fuar_firma_2012 f
on (s.cari = f.cari)
order by s.id DESC
By the way, you appear to by using MySQL (because your query is not parsable in any other dialect). You should tag your questions with the version of the database you are using.