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 関係です。たとえば、Shooter は 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を実行すると、140ではなく700の結果が得られます(予想どおり)

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 を使用して where に条件を追加する必要があります。

2-サブクエリ間の結合条件がありません

条件を追加する必要があるか、20K の結果が得られる理由は、INNER JOINWHEREがないためです。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 Fiddle がないと、これを実際に検証するのは複雑ですが、うまくいくはずだと確信しています。

于 2012-07-31T01:08:41.187 に答える
0

Stage_Scores には StageID ではなく Stage_ShootersID が必要ですか?

スコアを特定のシューターにリンクできるようにしたいようですが、テーブルのデザインではできません。

于 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 に答える