mySQL INNER JOIN有5个表

时间:2012-07-31 00:25:39

标签: mysql sql

我有5张桌子:

Stage:           ID, stage_name, stage_points, stage_number
Shooter:         ID, sh_uid, sh_al, sh_cat 
Stage_Shooters:  ID, StageID, ShooterID  
Score:           ID, miss, proc, bth, finalTime, shtr
Stage_Scores:    ID, StageID, ScoreID

Stage_Shooters和Stage_Scores是所述表的many_many关系。例如射手通过Stage_Shooters连接到舞台。

我正在尝试检索每个阶段的所有Shooter分数。目前我有5个阶段和28个射手,因此获得140分。我希望它最终看起来像这样:

--------------------------------------------------------------------------------
| Shooter              | Stage Name                | Stage Name                |
--------------------------------------------------------------------------------
| Alias       | Cat    | Raw   | M | P | B | Fin   | Raw   | M | P | B | Fin   |
--------------------------------------------------------------------------------
| Short Round | Junior | 24.00 | 0 | 0 | 1 | 19.00 | 7.00  | 0 | 0 | 1 | 6.00  |
--------------------------------------------------------------------------------
| Indy Jones  | Senior | 24.00 | 0 | 1 | 1 | 22.00 | 4.00  | 0 | 1 | 1 | 12.00 |
--------------------------------------------------------------------------------

为此,我想我必须做一个数据透视表,但是现在我只是想得到以下结果:

-----------------------------------------------------------------------
Stage Name | Shooter Alias | Shooter Category | Raw | M | P | B | Fin |
-----------------------------------------------------------------------
Stage Name | Shooter Alias | Shooter Category | Raw | M | P | B | Fin |
-----------------------------------------------------------------------

当我运行以下sql时,我得到700个结果而不是140个(如预期的那样)

SELECT ssh.stage_name, ssh.sh_al, ssh.sh_cat, ssc.time, ssc.M, ssc.P, ssc.B, ssc.Fin
FROM (
    SELECT s.stage_name, sh.sh_al, sh.sh_uid, sh.sh_cat
    FROM Shooter sh
    INNER JOIN Stage_Shooters stsh ON stsh.ShooterID = sh.ID
    INNER JOIN Stage s ON s.ID = stsh.StageID
) ssh
INNER JOIN (
    SELECT s.stage_name stageName, sc.time, sc.shtr, sc.miss M, sc.proc P, sc.bth B, sc.finalTime Fin
    FROM Score sc
    INNER JOIN Stage_Scores stsc ON stsc.ScoreID = sc.ID
    INNER JOIN Stage s ON s.ID = stsc.StageID
) ssc
WHERE ssh.sh_uid = ssc.shtr
ORDER BY ssh.sh_al

如果删除WHERE语句,我会得到19600个结果 如何使用连接或子查询来获取我需要的140行?

3 个答案:

答案 0 :(得分:4)

我有3条建议:

1-您没有加入相应舞台上的数据

如果您添加到查询AND ssh.stage_name = ssc.stage_name,只要您没有多个具有相同名称的舞台,它就应该有效。否则,您应该在两个子查询中添加舞台的ID,并将条件添加到使用这些ID而不是舞台名称的位置。

2-您缺少子查询之间的连接条件

您需要添加WHERE条件或获得20K结果的原因是因为INNER JOIN没有ON。也就是说,您可以将您在WHERE上添加的所有内容放在ON上。

这样的事情:

SELECT ssh.stage_name, ssh.sh_al, ssh.sh_cat, ssc.time, ssc.M, ssc.P, ssc.B, ssc.Fin
FROM (
    SELECT s.ID stageID, s.stage_name, sh.sh_al, sh.sh_uid, sh.sh_cat
    FROM Shooter sh
    INNER JOIN Stage_Shooters stsh ON stsh.ShooterID = sh.ID
    INNER JOIN Stage s ON s.ID = stsh.StageID
) ssh
INNER JOIN (
    SELECT s.ID stageID, s.stage_name stageName, sc.time, sc.shtr, sc.miss M, sc.proc P, sc.bth B, sc.finalTime Fin
    FROM Score sc
    INNER JOIN Stage_Scores stsc ON stsc.ScoreID = sc.ID
    INNER JOIN Stage s ON s.ID = stsc.StageID
) ssc
ON ssh.sh_uid = ssc.shtr AND ssh.stageID = ssc.stageID;

3-您可以使用单个查询完成整个事情

看起来您可以通过以下(更短)查询得到完全相同的结果:

SELECT
    stage_name,
    sh_al,
    sh_cat,
    time,
    miss AS M,
    proc AS p,
    bth AS b,
    finalTime AS Fin
FROM
    Shooter AS sh
    JOIN Stage_Shooters AS stsh ON stsh.ShooterID = sh.ID
    JOIN Stage AS s ON s.ID = stsh.StageID
    JOIN Stage_Scores AS stsc ON stsc.StageID = s.ID
    JOIN Score AS sc ON stsc.ScoreID = sc.ID AND sc.shtr = sh.ID

如果没有SQL小提琴,实际验证这一点很复杂,但我相信它应该有用。

答案 1 :(得分:0)

Stage_Scores是否应该有Stage_ShootersID而不是StageID?

看起来你希望能够将得分链接到特定的射手,但你的桌面设计不允许你这样做。

答案 2 :(得分:0)

只是通过查看我看到两组查询都连接到舞台表。我猜你可能需要在两个集合中选择舞台ID,然后在舞台ID和射手ID上加入ssh和ssc

SELECT ssh.stage_name, ssh.sh_al, ssh.sh_cat, ssc.time, ssc.M, ssc.P, ssc.B, ssc.Fin, s.ID as stageID
FROM (
    SELECT s.stage_name, sh.sh_al, sh.sh_uid, sh.sh_cat
    FROM Shooter sh
    INNER JOIN Stage_Shooters stsh ON stsh.ShooterID = sh.ID
    INNER JOIN Stage s ON s.ID = stsh.StageID
) ssh
INNER JOIN (
    SELECT s.stage_name stageName, sc.time, sc.shtr, sc.miss M, sc.proc P, sc.bth B, sc.finalTime Fin, s.ID as stageID
    FROM Score sc
    INNER JOIN Stage_Scores stsc ON stsc.ScoreID = sc.ID
    INNER JOIN Stage s ON s.ID = stsc.StageID
) ssc
WHERE ssh.sh_uid = ssc.shtr
AND ssh.stageID = ssc.stageID
ORDER BY ssh.sh_al