2016-04-05 32 views
1

Bir basketbol veritabanı için bir sorgu yazarken, oyunlar için oyunumuzda her biri bir takım kimliği olan bir kazanan kimliği ve bir kaybedeni kimliği vardır. Aşağıdaki iki soruyu denedim, her biri bana doğru bir şekilde kazanç sayısını veriyor, ancak bana kayıplar için aynı numarayı veriyor.İki tabloya iki kez katılma

SELECT team.name as Team_Name, COUNT(team.teamID=winner.winnerID) as Wins, COUNT(team.teamID=loser.loserID) as Losses 
FROM team join games winner on winner.winnerID=team.teamID join games loser on loser.loserID=team.teamID 
GROUP BY team.name 
ORDER BY Wins, Team_Name; 

SELECT team.name as Team_Name, COUNT(team.teamID=games.winnerID) as Wins, COUNT(team.teamID=games.loserID) as Losses 
FROM (team INNER JOIN games on games.winnerID=team.teamID) 
GROUP BY team.name 
ORDER BY Wins, team.name; 

Yardım?

DÜZENLEME: Unutmayın, sorgulamanın amacı her takımın galibiyet sayısını ve kayıp sayısını elde etmektir.

cevap

0

Toplamı, COUNT toplamı, NULL olmayan değerlerin sayısını alır. Bu, birleri ve sıfırları içerdiği anlamına gelir. Sayısal bir bağlamda Değerlendirilen

, bir eşitlik TRUE için 1 döner ve YANLIŞ için 0 döndürür, ve her iki tarafında (ya da her iki taraf) NULL ise sadece NULL döndürür.

Bunları eklemek ve sıfırları yok saymak için, bunun yerine bir SUM topağını kullanabilirsiniz.

Sorgudaki en büyük sorunlardan biri, winner ve loser arasındaki çapraz birleştirmeden dolayı çiftleri döndürme potansiyeli olmasıdır. Bir takımın 5 galibiyeti ve 4 kaybı varsa, sorgu 20 (= 5 x 4) satırlık bir ara grup üretecektir.

Bundan bir miktar kazanç ve kayıp elde etmek için, bir oyun için benzersiz bir tanımlayıcıya ihtiyacımız var (örneğin, oyun tablosundaki PRIMARY KEY olan bir oyun çubuğu sütunu). gameid'in farklı değerlerinin sayısı. Örneğin:

COUNT(DISTINCT IF(winner.winnerid=team.teamid,winner.gameid,NULL)) AS wins 

size galibiyet sayısını ve her bir takım için kayıpların sayısını elde edecek birkaç sorgu kalıbı yok. Biz sadece bir kez oyun tabloya katılıyor, bu yüzden çapraz ürünü almazsınız Bununla

SELECT t.name        AS team_name 
     , COUNT(IF(t.teamid=g.winnerid,1,NULL) AS wins 
     , COUNT(IF(t.teamid=g.loserid ,1,NULL) AS losses 
    FROM team 
    LEFT 
    JOIN games g 
    ON (g.winnerid = t.teamid OR g.loserid = t.teamid) 
    GROUP 
    BY t.name 
    ORDER 
    BY wins DESC 
     , t.name 

:

İşte bir örnek. Ayrıca, teamid,, winnerid'e eşit olmayan değilse, 0 yerine bir NULL döndüreceğimizi unutmayın. Böylece COUNT yalnızca tüm satırları değil, yalnızca kazananlar içerecektir.

Takım için oyunlarda ilgili satırların olmaması durumunda, bir dış birleştirmeyi (bir iç birleştirmeden ziyade) kullanırız. Bu, sıfır sayıyla bir takım döndürmemize izin veriyor.

Biz Örneğin, bir COUNT yerine SUM agrega kullanabilirsiniz:

SELECT t.name        AS team_name 
     , IFNULL(SUM(t.teamid=g.winnerid),0) AS wins 
     , IFNULL(SUM(t.teamid=g.loserid) ,0) AS losses 
    FROM team 
    LEFT 
    JOIN games g 
    ON (g.winnerid = t.teamid OR g.loserid = t.teamid) 
    GROUP 
    BY t.name 
    ORDER 
    BY wins DESC 
     , t.name 

SUM ile() biz NULL değerleri dönmek için bir potansiyele sahiptir. Bunları sıfırlara dönüştürmek için bir IFNULL işlevi kullanıyoruz.

Ayrıca, eşdeğer bir sonuç alabilmeniz için başka birçok sorgu deseni vardır. birleştirmeler kullanmak yerine, SELECT listesindeki ilişkili alt sorgular kullanın ...

SELECT t.name 
    , (SELECT COUNT(1) 
      FROM game w 
      WHERE w.winner_id = t.teamid 
     ) AS wins 
    , (SELECT COUNT(1) 
      FROM game l 
      WHERE l.loserid = t.teamid 
     ) AS losses 
    FROM team t 
ORDER BY wins DESC 
    , t.name