2

我有 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 连接到舞台。

我正在尝试检索每个阶段的所有射手分数。目前我有 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 行?

4

3 回答 3

4

我有 3 条建议:

1-您没有加入相应阶段的数据

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

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

您需要添加WHERE条件或获得 20K 结果的原因是因为没有ONINNER JOIN。也就是说你可以把你添加的所有东西放在 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 Fiddle,实际验证这一点很复杂,但我非常有信心它应该可以工作。

于 2012-07-31T01:08:41.187 回答
0

Stage_Scores 是否应该使用 Stage_ShootersID 而不是 StageID?

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

于 2012-07-31T00:47:33.317 回答
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
于 2012-07-31T00:53:46.713 回答