1

私はphp|mySQLを初めて使用する高校の教師であり、生徒のテストスコアを表示するクエリを開発しようとしています。課題は、特定のテストのスコアを表示し、スコアが投稿されていない場合はNULLを表示することです。私は2つのステップを1つのクエリにしようとしています:

  1. 提出されたテスト結果に基づいて、特定のコースの学生のリストを作成します。
  2. そのテストで各生徒のスコアを表示します。テストを受けていないためにスコアが存在しない場合は、名前とその横にNULLを表示します。

各評価のレコードを含む「テスト」テーブルには、次の列が含まれています。

test_id
assessment_id
username
score
maxScore
stopTime

各学生のレコードを含む「users」テーブルには、次の列が含まれています。

user_id
schoolId
username
first_name
last_name
section

望ましい結果:

username | last_name | first_name | schoolId | assessment_id | score | maxScore
------------------------------------------------------------------------------------
jadams1  | Adams     | Joe        | 111111   | 23            | 9     | 12
sbenson1 | Benson    | Sally      | 222222   | 23            | 10    | 12
csmith2  | Smith     | Charlie    | 555555   | NULL          | NULL  | NULL (hasn't taken quiz yet)
dthomp1  | Thompson  | David      | 666666   | 23            | 9     | 12

これまで私は多くのことを試みてきました。1つ目は基本的なLEFTJOINでした。これにより、学生ごとに1つの行が生成されますが、「tests.assessment_id」に値を指定しているため、クイズをまだ受けていない学生の行は表示されません。クイズの結果が存在する場合はそれを表示し、クイズを受験していない場合はNULLスコア値を含む学生の行を表示したいと思います。

SELECT
  users.last_name,
  users.first_name,
  tests.score,
  tests.maxScore
FROM users
  LEFT JOIN tests
    ON tests.username = users.username
WHERE tests.assessment_id = '23'
    AND users.section = 'S432-01'

上記は以下を生成します:

username | last_name | first_name | schoolId | assessment_id | score | maxScore
------------------------------------------------------------------------------
jadams1  | Adams     | Joe        | 111111   | 23            | 9     | 12
sbenson1 | Benson    | Sally      | 222222   | 23            | 10    | 12
dthomp1  | Thompson  | David      | 666666   | 23            | 9     | 12

以下は、より最近の反復です。練習クイズ(assessment_idが割り当てられていない)の行と本物の行を生成します。最終レポートでは、生徒ごとに1つの行のみを作成することが重要ですが、生徒を見逃さないようにすることが重要です。

SELECT DISTINCT
  users.username,
  users.last_name,
  users.first_name,
  users.schoolId,
  if(tests.assessment_id ='23','23','') AS assessment,
  if(tests.assessment_id ='23',tests.score,'') AS score,
  if(tests.assessment_id ='23',tests.maxScore,'') AS maxScore
FROM `users`
  LEFT JOIN tests
    ON tests.username = users.username
WHERE users.section = 'S432-01'
    AND (tests.assessment_id = '23'
      OR tests.assessment_id IS NULL)
ORDER BY users.last_name,users.first_name,tests.assessment_id

上記は以下を生成します:

username | last_name | first_name | schoolId  | assessment_id | score | maxScore
------------------------------------------------------------------------------------
jadams1  | Adams     | Joe        | 111111    | NULL          | NULL  | NULL
jadams1  | Adams     | Joe        | 111111    | 23            | 9     | 12
sbenson1 | Benson    | Sally      | 222222    | NULL          | NULL  | NULL
sbenson1 | Benson    | Sally      | 222222    | 23            | 10    | 12
csmith2  | Smith     | Charlie    | 555555    | NULL          | NULL. | NULL (hasn't taken quiz yet)
dthomp1  | Thompson  | David      | 666666    | NULL          | NULL. | NULL
dthomp1  | Thompson  | David      | 666666    | 23            | 9     | 12

これを単一のクエリで機能させる方法はありますか?パフォーマンスに問題があると思いますので、なるべくシンプルにしたいと思います。

ご協力いただきありがとうございます!-クリス

4

1 に答える 1

4

これはうまくいくでしょう、

SELECT  users.last_name,
        users.first_name,
        tests.score,
        tests.maxScore
FROM    users
        LEFT JOIN tests
              ON tests.username = users.username AND 
                 tests.assessment_id = '23'
WHERE   users.section = 'S432-01'

usersテーブルからすべてのレコードを取得していない理由は、すべての値を削除するのassessment_idと同じようにフィルタリングしたためです(評価を受けていない学生は、この列の値がnullになります)。すべての値を取得するには、句を上に移動します。23nulltests.assessment_id='23'ON

于 2013-02-03T13:44:23.867 に答える