我有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行?
答案 0 :(得分:4)
我有3条建议:
如果您添加到查询AND ssh.stage_name = ssc.stage_name
,只要您没有多个具有相同名称的舞台,它就应该有效。否则,您应该在两个子查询中添加舞台的ID,并将条件添加到使用这些ID而不是舞台名称的位置。
您需要添加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;
看起来您可以通过以下(更短)查询得到完全相同的结果:
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