2

私はSQLの経験はあまりありませんが、基本的なクエリを構築することはできますが、これは複雑すぎて解決できません。

それぞれが必要な結果を個別に提供する2つのクエリがありますが、必要な最終結果を得るにはそれらを組み合わせる必要があります。

1 つのクエリで、特定の学生のすべての「スコア」を取得し、平均を返します。もう 1 つのクエリでは、テーブルから最上位と最下位のレコードを取り除きます。

これらのクエリを組み合わせて、最初に最高スコアと最低スコアを取り除き、次に残りのレコードのみから平均スコアを返したいと考えています。使用する正しい構文を教えてください。

私のクエリ:


これは、すべての最高スコアと最低スコアを返します。

SELECT *
FROM `scores`
WHERE `tot_score` = (
SELECT MAX( `tot_score` )
FROM `scores` )
OR `tot_score` = (
SELECT MIN( `tot_score` )
FROM `scores` ) 

これは平均スコアを返します。

SELECT `pres_id`, COUNT( `pres_id` ) , ROUND( AVG( `tot_score` ) , 2 ) , `username`, `name`, `pres_day`
FROM `scores`, `users`
WHERE `users.id_user` = `scores.pres_id`
GROUP BY `pres_id`

これらをどのように組み合わせて必要な結果を得ることができますか?

4

2 に答える 2

5

単一のサブクエリで最小値と最大値の計算を行うことをお勧めします。where次に、フィルターする句を使用して、必要な行を簡単に取得できます。

SELECT s.`pres_id`, COUNT( `pres_id` ), ROUND( AVG( `tot_score` ) , 2 ) ,
       `username`, `name`, `pres_day`
FROM `scores` s join
     `users` u
     on u.id_user = s.pres_id join
     (select s.pres_id, max(tot_score) as maxts, min(tot_score) as mints
      from scores s
      group by s.pres_id
     ) ssum
     on u.id_user = ssum.pres_id
where s.tot_score > ssum.mints and s.tot_score < ssum.maxts
GROUP BY s.`pres_id`;

各生徒の最高点と最低点を取り除きたいと思います。すべての学生の最高値と最低値を省略したい場合は、次のようにします。

SELECT s.`pres_id`, COUNT( `pres_id` ), ROUND( AVG( `tot_score` ) , 2 ) ,
       `username`, `name`, `pres_day`
FROM `scores` s join
     `users` u
     on u.id_user = s.pres_id cross join
     (select max(tot_score) as maxts, min(tot_score) as mints
      from scores s
     ) ssum
where s.tot_score > ssum.mints and s.tot_score < ssum.maxts
GROUP BY s.`pres_id`;

編集:

学生のスコアが 1 つしかない場合にスコアを保持するための変更:

SELECT s.`pres_id`, COUNT( `pres_id` ), ROUND( AVG( `tot_score` ) , 2 ) ,
       `username`, `name`, `pres_day`
FROM `scores` s join
     `users` u
     on u.id_user = s.pres_id join
     (select s.pres_id, max(tot_score) as maxts, min(tot_score) as mints,
             count(*) as cnt
      from scores s
      group by s.pres_id
     ) ssum
     on u.id_user = ssum.pres_id
where (s.tot_score > ssum.mints and s.tot_score < ssum.maxts) or (cnt = 1)
GROUP BY s.`pres_id`;
于 2013-08-02T12:06:57.517 に答える
3

高/低スコア クエリを反転し、それを既存の平均クエリの結果セットとして使用できるはずです。

SELECT `pres_id`, COUNT( `pres_id` ) , ROUND( AVG( `tot_score` ) , 2 ) , `username`, `name`, `pres_day`
FROM (
    SELECT `tot_score`
    FROM `scores`
    WHERE `tot_score` <> (
    SELECT MAX( `tot_score` )
    FROM `scores` )
    OR `tot_score` <> (
    SELECT MIN( `tot_score` )
    FROM `scores` ) 
) AS `scores`, `users`
WHERE `users.id_user` = `scores.pres_id`
GROUP BY `pres_id`
于 2013-08-02T12:00:04.987 に答える