Mysql query problem

后端 未结 8 822
逝去的感伤
逝去的感伤 2020-12-22 03:24

I have a problem with my mysql query.

My database:

sections
id
section_name

grades
id
user_id
section_id
date
grade

I want my data

相关标签:
8条回答
  • 2020-12-22 03:52

    My solution involves the use of subquery to get the id of the latest grade and then passing it up to the query which then joins both sections and grades table to return section_name and grade. Please consider this more as a psuedocode than a valid sql query as I dont have time to test it. Might come back later to edit it

    SELECT section_name, grade FROM sections, grades WHERE sections.id = grades.id AND grades.id = (SELECT id FROM grades WHERE section_id = '$Id' ORDER by date DESC LIMIT 1)

    0 讨论(0)
  • 2020-12-22 03:54
    SELECT sections.section_name, grades.grade
    
                        FROM 
                        grades, 
                        sections 
    
                        WHERE 
                        sections.id = grades.section_id
    
                        AND
                        grades.user_id = '.$id.'
    
                        ORDER BY grades.date DESC
    
                        LIMIT 1
    

    try this?

    0 讨论(0)
  • 2020-12-22 03:56

    Lets assume we are looking for grades of user with id=1 (just to test query without php). You can replace it with '$Id' later.

    If your date column is precise enough to ensure it is unique for every grade you can use:

    SELECT s.section_name, g1.grade FROM
      ( SELECT g.section_id, max(g.date) AS last_grade_date
        FROM grades g
        WHERE g.user_id = 1
        GROUP BY g.section_id ) gd
      JOIN grades g1
        ON g1.date = gd.last_grade_date
      JOIN sections s
        ON s.id = gd.section_id
    

    If your date is not unique then you have to join grades back to itself on id found in dependent subquery:

    SELECT s.section_name, ga.grade FROM
      ( SELECT g1.section_id, max(g1.date) AS last_grade_date
        FROM grades g1
        WHERE g1.user_id = 1
        GROUP BY g1.section_id ) gmax
      JOIN grades ga
        ON ga.id =
          ( SELECT g2.id
            FROM grades g2
            WHERE g2.user_id = 1
            AND g2.section_id = gmax.section_id
            AND g2.date = gmax.last_grade_date
            LIMIT 1 )
      JOIN sections s
        ON s.id = gmax.section_id
    

    You need index on (user_id, section_id, date) for this query.

    ALTER TABLE grades ADD INDEX user_section_date( user_id, section_id, date ) ;
    

    @comment: Ok I'll try to explain the second query as it gives correct results for any case.

    In table g1 we take rows from grades for user with id=1, we group them by section and in every section we find a maximum date - which means most recent date. At this point we don't know yet which row exactly holds this most recent date, because we can select only columns that are in the group by or aggregate functions (like max()). Mysql allows to select other columns, like grade, called hidden columns (other dbs would just throw a syntax error), but is free to return any row from each group, usually not the one we want, and we want the one holding most recent date. If all rows have the same value, like user_id in this case, its ok, but we need grades, which can be different in every group. For small tables select can return the right one, thats why some people claim ordering by date can help, because they test it on small tables and see correct results, but it goes wrong once the table grows, there are row updates, deletes and so on.

    Basically we now have a list of sections and most recent dates and we need to find out grades. So we have to join this g1 table we just got to the grades table to find a row that holds the most recent date for every section. Id is the only column we are sure to be unique (if we don't join on unique column or unique list of columns we'll get more rows and we want exactly one) so we try to find this id in dependent subquery g2 (its a subquery that references values from outside, from gmax in this case, which is just an alias for g1, explained earlier).

    Once we have grade for every section_id the only thing left to do is to join that to sections table on section_id to get section_name instead of its id value.

    0 讨论(0)
  • 2020-12-22 03:57

    If I get this right you want the latest grade per section. This cannot be done simply with MySQL.

    You'd need a window function or a sequence generator, neither of which are available in MySQL. There is a workaround using variables, however. See this question for a similar use-case:

    MySQL query: Using UNION and getting row number as part of SELECT

    Additional background information here:

    SQL/mysql - Select distinct/UNIQUE but return all columns?

    What you'll likely end up doing is a big nested query that will look like this:

    select t.*
    from (select @rownum := @rownum + 1 rownum,
                 t.*
          from (select *
                  from grades join sections on sections.id = grades.section_id 
                 where user_id=$id order by grades.date desc
               ) t,
               (select @rownum := 0) r
          ) t
    where t.rownum = 1
    
    0 讨论(0)
  • 2020-12-22 03:59

    I recently had to do something similiar, but with T-SQL so you'll have to change it yourself to get it to work in MySQL (which I don't have installed here so I can't check for you I'm afraid).

    Add to the WHERE clause:

    AND grades.date = (SELECT TOP 1 date 
                         FROM grades 
                           WHERE date > GETDATE() 
                       ORDER BY ABS(CONVERT(FLOAT,GETDATE() - date)))
    

    GETDATE() is equivalent to NOW(), TOP 1 is like LIMIT 1 and the other functions, well I don't know the MySQL equivalents off the top of my head!

    0 讨论(0)
  • 2020-12-22 04:05
    SELECT grades.*,sections.* 
     FROM grades inner join sections on grades.sections_id = sections.id 
     where grades.user_id = '.$id.' 
     GROUP BY grades.section_id 
     ORDER BY grades.date DESC
    

    you can use this it is working 100%

    0 讨论(0)
提交回复
热议问题