2016-05-20 5 views
0

ありがとうstackoverflowコミュニティ!私はあなたから何年も前から多くのことを学んできましたが、最近アカウントを作成しました。私はこの質問への答えが明らかにどこかではないことを願っていますが、別の記事を読んでいれば、私は目を逸らすつもりです。ここに私の問題があります:入れ子になったSELECTは最高値を見つけ、見つからない場合は0を表示します。

私は最近、ネストされたSELECTを使用して、各生徒の最高スコアをテーブルから取得しました。私はちょっとしたトリックでそうしました。もう1つの投稿が教えてくれました。私はそれを学んだ正確な投稿を見つけることができませんが、ここでは本質的に同じトリックであるスニペットです。私はあなたがよくSQLに精通している場合、それはあなたに新しい何もない、想像:____ DESC BY

SELECT id, authorId, answer, votes 
FROM ( SELECT id, authorId, answer, votes 
     FROM answers 
     ORDER BY votes DESC) AS h 
GROUP BY authorId 

ORDERは、最後の値になり、あなたはそれだけで終わるので、最高のは、以前のすべてを上書き...私が正しく理解すれば。だから、それは素晴らしかったし、私はそれを自分の必要に合わせて調整しました。唯一の問題は、今ではもう1つの機能を追加したいと思っています。私はその上に脳細胞を入れています。私は寛大な人が私を真っ直ぐにしてくれることを願っています。私は "ロスター"テーブルから生徒の完全なリストを取得したいと思っていますし、学生のスコアがない場合は、私の "ホルダー"テーブルに "0"を表示したいと思います。 「あなたは私がコメントアウトその行を見ることができます

SELECT * 
FROM (
     SELECT 
     holder.id, 
     #IFNULL(holder.score, 0) AS score, 
     holder.score AS score, 
     holder.total, 
     holder.student_id AS stu_id, 
     holder.date AS date, 
     users.firstname AS first, 
     users.lastname AS last, 
     users.stu_number AS stuno, 
     assignments.name AS test, 
     rosters.p_id, 
     preps.period AS period, 
     preps.user 

     FROM holder 

     JOIN rosters 
     ON rosters.stu_id = holder.student_id 

     JOIN users 
     ON users.id = holder.student_id 

     JOIN assignments 
     ON assignments.id = holder.t_id 

     JOIN preps 
     ON preps.id = rosters.p_id 

     WHERE holder.visible = 0 
     AND preps.user = 1 
     AND assignments.user = 1 
     AND holder.t_id = 1 
     AND preps.period = 2 
     ORDER BY score DESC 
    ) x 
GROUP BY stuno 
ORDER BY last 

はそれを表示するために取得する私の微弱な試みの一つである:ここで私が持っている、と私はちょうどそれを行うには、それを微調整する方法を正確に知っていないものですNULLの場合は0を返しますが、動作していません。私は完全なリストを取得しますが、スコアが生徒のために見つからなければ、その生徒は私のリストに現れません。誰でも私に試してみるための解決策や考えがありますか?

私はJOINを過度に使用し、自分の人生を必要以上に困難にしていますか?私は主に独学ですから、私は基本にいくつかの穴があることを知っています。それは私がいくつかのクールなクールなプロジェクトを作成するのを止めていない...しかし、今は毎回、私は自分自身にいくつかの不必要な悲しみを引き起こしていると確信しています。

/////////////////////////////////////////////////////////////////////////////それは私のテーブルからの情報をつかむように、ここで/

は、私は以下の回答でやっていることです:

SELECT au.stu_id, 
    COALESCE(t.id, 0) as id, 
    COALESCE(t.score , 0) as score    
FROM rosters au 
LEFT JOIN (
    SELECT * 
     FROM (
      SELECT a.*, 
       @rownum := if(@prev_value = student_id, 
       @rownum + 1, 
      1) rn, 
     @prev_value := student_id as prev  
     FROM holder a, 
     (SELECT @rownum := 0, @prev_value := '') r 
     ORDER BY student_id, score DESC 
    ) T 
    WHERE T.rn = 1) T 
ON au.stu_id = T.student_id 

それがない学生は表示されません除きので、これは、作業素晴らしいです与えられたテストの得点があります。彼らのスコアが「ホルダー」テーブルに見つからない場合、私はそれを「0」として表示したいと思います。

/////////////

お待ちください!私は間違っているかもしれない...私はそれが正しく働いていると思う。私はいくつかのことを微調整して、あなたに戻ってくる必要があります。ところで、お世話になりました。

答えて

1

最初のaproachは、MySQLのデザインが悪いためにのみ動作します。

右aproachは

SQL Fiddle Demo

SELECT a.id, a.authorId, a.answer, a.votes 
FROM ( SELECT authorId, 
       MAX(votes) as votes 
     FROM answers 
     GROUP BY authorId) AS h 
JOIN answers a 
    ON a.authorId = h.authorId 
AND a.votes = h.votes; 

OUTPUT

| id | authorId | answer | votes | 
|----|----------|--------|-------| 
| 2 |  a |  x2 | 21 | 
| 4 |  b |  x1 | 23 | ==> 
| 5 |  b |  x2 | 23 | ==> duplicates max value are possible 

しかし、いくつかの答えは同じスコアを持っている場合、この問題を持っていなければなりません。表示するロジックを決定するためには、ロジックを含める必要があります。

また、variableを使用して最高得点を得ることもできます。

| id | authorId | answer | votes | rn | prev | 
|----|----------|--------|-------|----|------| 
| 4 |  b |  x1 | 23 | 1 | b | => only one is show but would  
| 2 |  a |  x2 | 21 | 1 | a | be random unless you specify some rule. 

SELECT * 
FROM (
     SELECT a.*, 
      @rownum := if(@prev_value = authorId, 
          @rownum + 1, 
          1) rn, 
      @prev_value := authorId as prev  
     FROM answers a, 
      (SELECT @rownum := 0, @prev_value := '') r 
     ORDER BY authorId, votes DESC 
    ) T 
WHERE T.rn = 1; 

OUTPUTは、今すぐあなたの質問に対して、あなたも得点なしで学生を取得する代わりにJOINLEFT JOINを使用する必要があります。私は `COALESCE`が、どのようなエイリアスイム欠落を含むことができ、この

SELECT au.authorId, 
     COALESCE(t.id, 0) as id, 
     COALESCE(t.answer , 0) as answer , 
     COALESCE(t.votes , 0) as votes    
FROM authors au 
LEFT JOIN (
      SELECT * 
      FROM (
        SELECT a.*, 
         @rownum := if(@prev_value = authorId, 
             @rownum + 1, 
             1) rn, 
         @prev_value := authorId as prev  
        FROM answers a, 
         (SELECT @rownum := 0, @prev_value := '') r 
        ORDER BY authorId, votes DESC 
       ) T 
      WHERE T.rn = 1) T 
     ON au.authorId = T.authorId 

OUTPUT

| authorId | id | answer | votes | 
|----------|----|--------|-------| 
|  a | 2 |  x2 | 21 | 
|  b | 4 |  x1 | 23 | 
|  c | 0 |  0 |  0 | 
+0

@Strawberryよう

何か? –

+0

さて、あなたのSQLの書き込みスキルは私の弱いレベルを超えていると言う必要があります。私は、スキーマやテーブルのどんなものとでも一致するようにすべてのものを試して修正するのは怖すぎましたが、実際には成功しました。 1つの例外を除いて、今のところすべてが吐き出されます。生徒が私のロスターテーブルに存在するが、ホルダーテーブルにスコアがない場合、生徒はリストに表示されません。 –

+0

sqlFiddleでスキーマを作成してみてください。後で詳しく見ていきます。 –

関連する問題