How to find the avg of better films rating in MySQL












1















I have a table
Films



id  release_year    category_id rating
1 2015 1 8
2 2015 2 8.5
3 2015 3 9
4 2016 2 8.2
5 2016 1 8.4
6 2017 2 7


I want to add a new column "avg_better_films" to find an average rating of all better films in its release year



the output should be



id  release_year    category_id rating  avg_better_films
1 2015 1 8 8.75
2 2015 2 8.5 9
3 2015 3 9 Not Available
4 2016 2 8.2 8.4
5 2016 1 8.4 Not Available
6 2017 2 7 Not Available


and you can see, when the film has the best rating in the release year
it will show "Not Available"



Do you know how to get this output in MySQL










share|improve this question




















  • 3





    Easy way: correlated subquery.

    – jarlh
    Nov 16 '18 at 10:06






  • 1





    Please dont use images; Formatted code text is better. I have rollbacked to previous "OK" version of the question.

    – Madhur Bhaiya
    Nov 16 '18 at 10:12
















1















I have a table
Films



id  release_year    category_id rating
1 2015 1 8
2 2015 2 8.5
3 2015 3 9
4 2016 2 8.2
5 2016 1 8.4
6 2017 2 7


I want to add a new column "avg_better_films" to find an average rating of all better films in its release year



the output should be



id  release_year    category_id rating  avg_better_films
1 2015 1 8 8.75
2 2015 2 8.5 9
3 2015 3 9 Not Available
4 2016 2 8.2 8.4
5 2016 1 8.4 Not Available
6 2017 2 7 Not Available


and you can see, when the film has the best rating in the release year
it will show "Not Available"



Do you know how to get this output in MySQL










share|improve this question




















  • 3





    Easy way: correlated subquery.

    – jarlh
    Nov 16 '18 at 10:06






  • 1





    Please dont use images; Formatted code text is better. I have rollbacked to previous "OK" version of the question.

    – Madhur Bhaiya
    Nov 16 '18 at 10:12














1












1








1








I have a table
Films



id  release_year    category_id rating
1 2015 1 8
2 2015 2 8.5
3 2015 3 9
4 2016 2 8.2
5 2016 1 8.4
6 2017 2 7


I want to add a new column "avg_better_films" to find an average rating of all better films in its release year



the output should be



id  release_year    category_id rating  avg_better_films
1 2015 1 8 8.75
2 2015 2 8.5 9
3 2015 3 9 Not Available
4 2016 2 8.2 8.4
5 2016 1 8.4 Not Available
6 2017 2 7 Not Available


and you can see, when the film has the best rating in the release year
it will show "Not Available"



Do you know how to get this output in MySQL










share|improve this question
















I have a table
Films



id  release_year    category_id rating
1 2015 1 8
2 2015 2 8.5
3 2015 3 9
4 2016 2 8.2
5 2016 1 8.4
6 2017 2 7


I want to add a new column "avg_better_films" to find an average rating of all better films in its release year



the output should be



id  release_year    category_id rating  avg_better_films
1 2015 1 8 8.75
2 2015 2 8.5 9
3 2015 3 9 Not Available
4 2016 2 8.2 8.4
5 2016 1 8.4 Not Available
6 2017 2 7 Not Available


and you can see, when the film has the best rating in the release year
it will show "Not Available"



Do you know how to get this output in MySQL







mysql sql database






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 16 '18 at 10:11









Madhur Bhaiya

19.6k62336




19.6k62336










asked Nov 16 '18 at 10:05









RlearnRlearn

153




153








  • 3





    Easy way: correlated subquery.

    – jarlh
    Nov 16 '18 at 10:06






  • 1





    Please dont use images; Formatted code text is better. I have rollbacked to previous "OK" version of the question.

    – Madhur Bhaiya
    Nov 16 '18 at 10:12














  • 3





    Easy way: correlated subquery.

    – jarlh
    Nov 16 '18 at 10:06






  • 1





    Please dont use images; Formatted code text is better. I have rollbacked to previous "OK" version of the question.

    – Madhur Bhaiya
    Nov 16 '18 at 10:12








3




3





Easy way: correlated subquery.

– jarlh
Nov 16 '18 at 10:06





Easy way: correlated subquery.

– jarlh
Nov 16 '18 at 10:06




1




1





Please dont use images; Formatted code text is better. I have rollbacked to previous "OK" version of the question.

– Madhur Bhaiya
Nov 16 '18 at 10:12





Please dont use images; Formatted code text is better. I have rollbacked to previous "OK" version of the question.

– Madhur Bhaiya
Nov 16 '18 at 10:12












3 Answers
3






active

oldest

votes


















1















  • We can use a Correlated Subquery to calculate the Average rating for the "better films" for the same year.

  • Subquery would return null in case of no better films for a specific film and year.

  • We can then use Coalesce() function to handle the case when there is no "better film" found for the year.

  • Thanks to @Strawberry in comments, we need to do + 0 to the result of subquery, so that MySQL considers it as number


Try the following:



SELECT
t1.id,
t1.release_year,
t1.category_id,
t1.rating,
COALESCE(
(
SELECT AVG(t2.rating)
FROM Films AS t2
WHERE t2.rating > t1.rating AND -- higher rating films
t2.release_year = t1.release_year -- films from same year
) + 0,
'Not Available' -- handle null result of subquery
) AS avg_better_films
FROM Films AS t1


SQL Fiddle: http://sqlfiddle.com/#!9/4960ea/3






share|improve this answer


























  • Hi Madhur, the "avg_better_films" for each film is the avg of the films which have a better rating than it. If there are two better films, it should calculate the avg of the two films. If there is just one better film, it should just show the better film's rating. I believe correlated subquery is the way to work, but I don't how to calculate the better avg for each film differently

    – Rlearn
    Nov 16 '18 at 10:20













  • @Rlearn my query is doing the same. It is calculating it for every film only. if there are better films in the same year, then it calculates average of ratings; otherwise return Not Available

    – Madhur Bhaiya
    Nov 16 '18 at 10:22











  • sqlfiddle.com/#!9/4960ea/3

    – Strawberry
    Nov 16 '18 at 10:36











  • @Rlearn check the updated answer please.

    – Madhur Bhaiya
    Nov 16 '18 at 10:41











  • @Strawberry thanks. Just curious that isn't Avg() function supposed to return either a number or null. What am I missing here ?

    – Madhur Bhaiya
    Nov 16 '18 at 10:41



















0














you can try using scalar subquery



select *, (select avg(rating) from Films b on a.release_year=b.release_year) as avg_film_Rating
from Films a





share|improve this answer































    0














    This is tricky, because you need to output the results as a string, not a number. If any value is a string, all must be.



    I would recommend a correlated subquery that looks like:



    SELECT f.*,
    (SELECT COALESCE(FORMAT(AVG(t2.rating), 2), 'Not Available)
    FROM Films f2
    WHERE f2.rating > f.rating AND
    f2.release_year = f.release_year
    ) AS avg_better_films
    FROM Films f


    Notes:




    • Table aliases should be abbreviations for the table name.

    • If no rows match the WHERE clause in the subquery, then AVG() returns NULL. Hence, the COALESCE()can be in the subquery.


    • FORMAT() is used to convert the average rating to a string.






    share|improve this answer
























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53335518%2fhow-to-find-the-avg-of-better-films-rating-in-mysql%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1















      • We can use a Correlated Subquery to calculate the Average rating for the "better films" for the same year.

      • Subquery would return null in case of no better films for a specific film and year.

      • We can then use Coalesce() function to handle the case when there is no "better film" found for the year.

      • Thanks to @Strawberry in comments, we need to do + 0 to the result of subquery, so that MySQL considers it as number


      Try the following:



      SELECT
      t1.id,
      t1.release_year,
      t1.category_id,
      t1.rating,
      COALESCE(
      (
      SELECT AVG(t2.rating)
      FROM Films AS t2
      WHERE t2.rating > t1.rating AND -- higher rating films
      t2.release_year = t1.release_year -- films from same year
      ) + 0,
      'Not Available' -- handle null result of subquery
      ) AS avg_better_films
      FROM Films AS t1


      SQL Fiddle: http://sqlfiddle.com/#!9/4960ea/3






      share|improve this answer


























      • Hi Madhur, the "avg_better_films" for each film is the avg of the films which have a better rating than it. If there are two better films, it should calculate the avg of the two films. If there is just one better film, it should just show the better film's rating. I believe correlated subquery is the way to work, but I don't how to calculate the better avg for each film differently

        – Rlearn
        Nov 16 '18 at 10:20













      • @Rlearn my query is doing the same. It is calculating it for every film only. if there are better films in the same year, then it calculates average of ratings; otherwise return Not Available

        – Madhur Bhaiya
        Nov 16 '18 at 10:22











      • sqlfiddle.com/#!9/4960ea/3

        – Strawberry
        Nov 16 '18 at 10:36











      • @Rlearn check the updated answer please.

        – Madhur Bhaiya
        Nov 16 '18 at 10:41











      • @Strawberry thanks. Just curious that isn't Avg() function supposed to return either a number or null. What am I missing here ?

        – Madhur Bhaiya
        Nov 16 '18 at 10:41
















      1















      • We can use a Correlated Subquery to calculate the Average rating for the "better films" for the same year.

      • Subquery would return null in case of no better films for a specific film and year.

      • We can then use Coalesce() function to handle the case when there is no "better film" found for the year.

      • Thanks to @Strawberry in comments, we need to do + 0 to the result of subquery, so that MySQL considers it as number


      Try the following:



      SELECT
      t1.id,
      t1.release_year,
      t1.category_id,
      t1.rating,
      COALESCE(
      (
      SELECT AVG(t2.rating)
      FROM Films AS t2
      WHERE t2.rating > t1.rating AND -- higher rating films
      t2.release_year = t1.release_year -- films from same year
      ) + 0,
      'Not Available' -- handle null result of subquery
      ) AS avg_better_films
      FROM Films AS t1


      SQL Fiddle: http://sqlfiddle.com/#!9/4960ea/3






      share|improve this answer


























      • Hi Madhur, the "avg_better_films" for each film is the avg of the films which have a better rating than it. If there are two better films, it should calculate the avg of the two films. If there is just one better film, it should just show the better film's rating. I believe correlated subquery is the way to work, but I don't how to calculate the better avg for each film differently

        – Rlearn
        Nov 16 '18 at 10:20













      • @Rlearn my query is doing the same. It is calculating it for every film only. if there are better films in the same year, then it calculates average of ratings; otherwise return Not Available

        – Madhur Bhaiya
        Nov 16 '18 at 10:22











      • sqlfiddle.com/#!9/4960ea/3

        – Strawberry
        Nov 16 '18 at 10:36











      • @Rlearn check the updated answer please.

        – Madhur Bhaiya
        Nov 16 '18 at 10:41











      • @Strawberry thanks. Just curious that isn't Avg() function supposed to return either a number or null. What am I missing here ?

        – Madhur Bhaiya
        Nov 16 '18 at 10:41














      1












      1








      1








      • We can use a Correlated Subquery to calculate the Average rating for the "better films" for the same year.

      • Subquery would return null in case of no better films for a specific film and year.

      • We can then use Coalesce() function to handle the case when there is no "better film" found for the year.

      • Thanks to @Strawberry in comments, we need to do + 0 to the result of subquery, so that MySQL considers it as number


      Try the following:



      SELECT
      t1.id,
      t1.release_year,
      t1.category_id,
      t1.rating,
      COALESCE(
      (
      SELECT AVG(t2.rating)
      FROM Films AS t2
      WHERE t2.rating > t1.rating AND -- higher rating films
      t2.release_year = t1.release_year -- films from same year
      ) + 0,
      'Not Available' -- handle null result of subquery
      ) AS avg_better_films
      FROM Films AS t1


      SQL Fiddle: http://sqlfiddle.com/#!9/4960ea/3






      share|improve this answer
















      • We can use a Correlated Subquery to calculate the Average rating for the "better films" for the same year.

      • Subquery would return null in case of no better films for a specific film and year.

      • We can then use Coalesce() function to handle the case when there is no "better film" found for the year.

      • Thanks to @Strawberry in comments, we need to do + 0 to the result of subquery, so that MySQL considers it as number


      Try the following:



      SELECT
      t1.id,
      t1.release_year,
      t1.category_id,
      t1.rating,
      COALESCE(
      (
      SELECT AVG(t2.rating)
      FROM Films AS t2
      WHERE t2.rating > t1.rating AND -- higher rating films
      t2.release_year = t1.release_year -- films from same year
      ) + 0,
      'Not Available' -- handle null result of subquery
      ) AS avg_better_films
      FROM Films AS t1


      SQL Fiddle: http://sqlfiddle.com/#!9/4960ea/3







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 16 '18 at 10:40

























      answered Nov 16 '18 at 10:10









      Madhur BhaiyaMadhur Bhaiya

      19.6k62336




      19.6k62336













      • Hi Madhur, the "avg_better_films" for each film is the avg of the films which have a better rating than it. If there are two better films, it should calculate the avg of the two films. If there is just one better film, it should just show the better film's rating. I believe correlated subquery is the way to work, but I don't how to calculate the better avg for each film differently

        – Rlearn
        Nov 16 '18 at 10:20













      • @Rlearn my query is doing the same. It is calculating it for every film only. if there are better films in the same year, then it calculates average of ratings; otherwise return Not Available

        – Madhur Bhaiya
        Nov 16 '18 at 10:22











      • sqlfiddle.com/#!9/4960ea/3

        – Strawberry
        Nov 16 '18 at 10:36











      • @Rlearn check the updated answer please.

        – Madhur Bhaiya
        Nov 16 '18 at 10:41











      • @Strawberry thanks. Just curious that isn't Avg() function supposed to return either a number or null. What am I missing here ?

        – Madhur Bhaiya
        Nov 16 '18 at 10:41



















      • Hi Madhur, the "avg_better_films" for each film is the avg of the films which have a better rating than it. If there are two better films, it should calculate the avg of the two films. If there is just one better film, it should just show the better film's rating. I believe correlated subquery is the way to work, but I don't how to calculate the better avg for each film differently

        – Rlearn
        Nov 16 '18 at 10:20













      • @Rlearn my query is doing the same. It is calculating it for every film only. if there are better films in the same year, then it calculates average of ratings; otherwise return Not Available

        – Madhur Bhaiya
        Nov 16 '18 at 10:22











      • sqlfiddle.com/#!9/4960ea/3

        – Strawberry
        Nov 16 '18 at 10:36











      • @Rlearn check the updated answer please.

        – Madhur Bhaiya
        Nov 16 '18 at 10:41











      • @Strawberry thanks. Just curious that isn't Avg() function supposed to return either a number or null. What am I missing here ?

        – Madhur Bhaiya
        Nov 16 '18 at 10:41

















      Hi Madhur, the "avg_better_films" for each film is the avg of the films which have a better rating than it. If there are two better films, it should calculate the avg of the two films. If there is just one better film, it should just show the better film's rating. I believe correlated subquery is the way to work, but I don't how to calculate the better avg for each film differently

      – Rlearn
      Nov 16 '18 at 10:20







      Hi Madhur, the "avg_better_films" for each film is the avg of the films which have a better rating than it. If there are two better films, it should calculate the avg of the two films. If there is just one better film, it should just show the better film's rating. I believe correlated subquery is the way to work, but I don't how to calculate the better avg for each film differently

      – Rlearn
      Nov 16 '18 at 10:20















      @Rlearn my query is doing the same. It is calculating it for every film only. if there are better films in the same year, then it calculates average of ratings; otherwise return Not Available

      – Madhur Bhaiya
      Nov 16 '18 at 10:22





      @Rlearn my query is doing the same. It is calculating it for every film only. if there are better films in the same year, then it calculates average of ratings; otherwise return Not Available

      – Madhur Bhaiya
      Nov 16 '18 at 10:22













      sqlfiddle.com/#!9/4960ea/3

      – Strawberry
      Nov 16 '18 at 10:36





      sqlfiddle.com/#!9/4960ea/3

      – Strawberry
      Nov 16 '18 at 10:36













      @Rlearn check the updated answer please.

      – Madhur Bhaiya
      Nov 16 '18 at 10:41





      @Rlearn check the updated answer please.

      – Madhur Bhaiya
      Nov 16 '18 at 10:41













      @Strawberry thanks. Just curious that isn't Avg() function supposed to return either a number or null. What am I missing here ?

      – Madhur Bhaiya
      Nov 16 '18 at 10:41





      @Strawberry thanks. Just curious that isn't Avg() function supposed to return either a number or null. What am I missing here ?

      – Madhur Bhaiya
      Nov 16 '18 at 10:41













      0














      you can try using scalar subquery



      select *, (select avg(rating) from Films b on a.release_year=b.release_year) as avg_film_Rating
      from Films a





      share|improve this answer




























        0














        you can try using scalar subquery



        select *, (select avg(rating) from Films b on a.release_year=b.release_year) as avg_film_Rating
        from Films a





        share|improve this answer


























          0












          0








          0







          you can try using scalar subquery



          select *, (select avg(rating) from Films b on a.release_year=b.release_year) as avg_film_Rating
          from Films a





          share|improve this answer













          you can try using scalar subquery



          select *, (select avg(rating) from Films b on a.release_year=b.release_year) as avg_film_Rating
          from Films a






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 16 '18 at 10:08









          fa06fa06

          18.4k21018




          18.4k21018























              0














              This is tricky, because you need to output the results as a string, not a number. If any value is a string, all must be.



              I would recommend a correlated subquery that looks like:



              SELECT f.*,
              (SELECT COALESCE(FORMAT(AVG(t2.rating), 2), 'Not Available)
              FROM Films f2
              WHERE f2.rating > f.rating AND
              f2.release_year = f.release_year
              ) AS avg_better_films
              FROM Films f


              Notes:




              • Table aliases should be abbreviations for the table name.

              • If no rows match the WHERE clause in the subquery, then AVG() returns NULL. Hence, the COALESCE()can be in the subquery.


              • FORMAT() is used to convert the average rating to a string.






              share|improve this answer




























                0














                This is tricky, because you need to output the results as a string, not a number. If any value is a string, all must be.



                I would recommend a correlated subquery that looks like:



                SELECT f.*,
                (SELECT COALESCE(FORMAT(AVG(t2.rating), 2), 'Not Available)
                FROM Films f2
                WHERE f2.rating > f.rating AND
                f2.release_year = f.release_year
                ) AS avg_better_films
                FROM Films f


                Notes:




                • Table aliases should be abbreviations for the table name.

                • If no rows match the WHERE clause in the subquery, then AVG() returns NULL. Hence, the COALESCE()can be in the subquery.


                • FORMAT() is used to convert the average rating to a string.






                share|improve this answer


























                  0












                  0








                  0







                  This is tricky, because you need to output the results as a string, not a number. If any value is a string, all must be.



                  I would recommend a correlated subquery that looks like:



                  SELECT f.*,
                  (SELECT COALESCE(FORMAT(AVG(t2.rating), 2), 'Not Available)
                  FROM Films f2
                  WHERE f2.rating > f.rating AND
                  f2.release_year = f.release_year
                  ) AS avg_better_films
                  FROM Films f


                  Notes:




                  • Table aliases should be abbreviations for the table name.

                  • If no rows match the WHERE clause in the subquery, then AVG() returns NULL. Hence, the COALESCE()can be in the subquery.


                  • FORMAT() is used to convert the average rating to a string.






                  share|improve this answer













                  This is tricky, because you need to output the results as a string, not a number. If any value is a string, all must be.



                  I would recommend a correlated subquery that looks like:



                  SELECT f.*,
                  (SELECT COALESCE(FORMAT(AVG(t2.rating), 2), 'Not Available)
                  FROM Films f2
                  WHERE f2.rating > f.rating AND
                  f2.release_year = f.release_year
                  ) AS avg_better_films
                  FROM Films f


                  Notes:




                  • Table aliases should be abbreviations for the table name.

                  • If no rows match the WHERE clause in the subquery, then AVG() returns NULL. Hence, the COALESCE()can be in the subquery.


                  • FORMAT() is used to convert the average rating to a string.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 16 '18 at 12:20









                  Gordon LinoffGordon Linoff

                  792k36316419




                  792k36316419






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53335518%2fhow-to-find-the-avg-of-better-films-rating-in-mysql%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Xamarin.iOS Cant Deploy on Iphone

                      Glorious Revolution

                      Dulmage-Mendelsohn matrix decomposition in Python