How to select a specific group of elements from a database?
I'm working on a database which can be synthetized like:
TAB1: NICK, COUNTRY
TAB2: PLAYER, FRIEND
In TAB2, PLAYER and FRIEND both can connect to respective a TAB1.NICK; NICK is a primary key, PLAYER and FRIEND are both foreign keys.
I need to find how many players are friends only with people from the same country, but, after a couple of afternoons I still can't manage to do it...
The last thing I tried:
select count(*) from TAB1 as p1
join TAB2 as f1 on p1.nick = f1.player
join TAB1 as p2 on f1.friend = p2.nick
where p1.开发者_Go百科country is not null and p2.country is not null
and p1.country = p2.country
and not exists (select * from TAB1 as p0
join TAB2 as f0 on p0.nick = f0.nick
join TAB1 as p3 on f0.friend = p3.nickname
where p0.country is not null and p3.country is not null
and p0.country <> p3.country)
Build the query up piece-meal - start with the easier parts, and continue to the harder. The key observation to making it work is that you need to use two joins to the same table. This query gives the list of pairs where the two people come from the same country:
SELECT p1.nick, p1.country, p2.nick, p2.country
FROM tab2
JOIN tab1 AS p1 ON tab2.player = p1.nick
JOIN tab1 AS p2 ON tab2.friend = p2.nick
WHERE p1.country = p2.country
This counts the number of players with one or more friends from the same country:
SELECT COUNT(DISTINCT p1.nick)
FROM tab2
JOIN tab1 AS p1 ON tab2.player = p1.nick
JOIN tab1 AS p2 ON tab2.friend = p2.nick
WHERE p1.country = p2.country
And, if what you are after is people who only have friends from the same country as they come from (as suggested in the comment), then you need to establish that the player has no friends where the friend's country is not the player's country. You get into the interesting question: does some who has no friends get counted? Since they don't have any friends from the same country, they're not counted by the query below:
SELECT COUNT(DISTINCT p1.nick)
FROM tab2
JOIN tab1 AS p1 ON tab2.player = p1.nick
JOIN tab1 AS p2 ON tab2.friend = p2.nick
WHERE p1.country = p2.country
AND NOT EXISTS
(SELECT *
FROM tab2 AS t2
JOIN tab1 AS p3 ON t2.player = p3.nick
JOIN tab1 AS p4 ON t2.friend = p4.nick
WHERE p3.country != p4.country
AND p3.nick = p1.nick
)
This says "players who have at least one friend from their own country and where there is no friend for the player who comes from a different country".
SELECT TAB2.PLAYER, TAB1.COUNTRY
FROM TAB2 PLAYER_TAB2
JOIN TAB1 PLAYER_TAB1 ON TAB1.NICK = TAB2.PLAYER
WHERE NOT EXISTS (SELECT NULL
FROM TAB2
JOIN TAB1 ON TAB1.NICK = TAB2.FRIEND
AND TAB1.COUNTRY != PLAYER_TAB1.COUNTRY
WHERE TAB2.PLAYER = PLAYER_TAB2.PLAYER)
精彩评论