2016-10-14 6 views
1

J'essaye de retourner une requête qui montrera combien de fois un joueur a joué dans une partie et combien de fois il/elle a gagné. Voilà ce que j'ai jusqu'à présent, coincé sur la dernière requête de jointureComment joindre ces deux requêtes PSQL ensemble correctement?

Lien vers mon violon SQL: http://sqlfiddle.com/#!15/46b2a/52

J'ai deux tables:

CREATE TABLE player(
id serial PRIMARY KEY NOT NULL, 
name varchar(255) NOT NULL 
); 

CREATE TABLE match(
id serial PRIMARY KEY, 
winner serial REFERENCES player(id) NOT NULL, 
loser serial REFERENCES player(id) NOT NULL CHECK (loser != winner) 
); 

CREATE SEQUENCE playerid_sequence 
start 1 
increment 1; 

CREATE SEQUENCE matchid_sequence 
start 1 
increment 1; 

Je peuplaient mes tables avec quelques exemples des insertions :

--Player Insertion 
INSERT INTO player VALUES(nextval('playerid_sequence'), 'Kevin'); 
INSERT INTO player VALUES(nextval('playerid_sequence'), 'Dennis'); 
INSERT INTO player VALUES(nextval('playerid_sequence'), 'George'); 
INSERT INTO player VALUES(nextval('playerid_sequence'), 'Michael'); 

--Match Insertion 
INSERT INTO match VALUES(nextval('matchid_sequence'), 1, 2); 
INSERT INTO match VALUES(nextval('matchid_sequence'), 1, 3); 
INSERT INTO match VALUES(nextval('matchid_sequence'), 1, 4); 
INSERT INTO match VALUES(nextval('matchid_sequence'), 2, 3); 

J'ai créé deux requêtes SQL:

--How many did a player win? 
SELECT player.id, player.name, count(player.name) as wins FROM player, match 
WHERE player.id = match.winner GROUP by player.name, player.id ORDER BY wins DESC; 

--How many matches did a particular player participate in? 
SELECT player.id, player.name, count(player.name) as matches_played 
FROM player, match 
WHERE player.id = match.winner OR player.id = match.loser 
GROUP by player.name, player.id 
ORDER by matches_played DESC; 

J'ai fait pour tenter de les rejoindre:

SELECT 
* 
FROM 
(SELECT player.id, player.name, count(player.name) as wins FROM player, match 
WHERE player.id = match.winner GROUP by player.name, player.id ORDER BY wins DESC) t1 
FULL OUTER JOIN 
(SELECT player.id as id, count(player.name) as matches_played 
FROM player, match 
WHERE player.id = match.winner OR player.id = match.loser 
GROUP by player.id 
ORDER by matches_played DESC) t2 
ON t1.id = t2.id; 

La jointure ci-dessus requête renvoie uniquement l'ensemble des joueurs de t1, alors que je veux revenir tous les joueurs de t2. Je veux: id de joueur | nom | gagne | total des parties jouées pour tous les joueurs, avec 0 dans la colonne des gains s'ils n'ont pas gagné.

J'ai:

id name wins id matches_played 
1 Kevin 3  1 3 
2 Dennis 1  2 2 
(null) (null) (null) 4 1 
(null) (null) (null) 3 2 

Répondre

1

Je pense que la requête peut être simplifiée:

select p.id, p.name, 
     count(case when m.winner = p.id then 'X' end) as wins, 
     count(m.id) as matches_played 
    from player p 
    left join match m 
    on m.winner = p.id or m.loser = p.id 
group by p.id, p.name; 

SQL Fiddle Demo

La clé est que vous voulez joindre à gauche sur la table match. Le reste est une simple agrégation conditionnelle.