Как использовать join и order_by с несколькими записями в SQL / SQLalchemy? - PullRequest
0 голосов
/ 25 апреля 2018

У меня 2 таблицы выглядит так:

student_info:

| student_id | major |
|------------|-------|
| 1001       | CS    |
| 1002       | CS    |
| 1003       | CS    |
| 1004       | CS    |
| 1005       | BI    |

student_grade:

| student_id | course | semester    | grade |
|------------|--------|-------------|-------|
| 1001       | CS.201 | 2016.Spring | 100   |
| 1001       | CS.202 | 2016.Fall   | 90    |
| 1001       | EE.201 | 2016.Spring | 90    |
| 1002       | CS.201 | 2016.Spring | 70    |
| 1002       | CS.202 | 2016.Fall   | 70    |
| 1003       | CS.201 | 2016.Spring | 99    |
| 1003       | EE.201 | 2016.Fall   | 90    |
| 1003       | CS.202 | 2016.Fall   | 90    |
| 1004       | CS.201 | 2016.Spring | 99    |
| 1004       | BI.202 | 2016.Fall   | 80    |
| 1005       | CS.201 | 2017.Spring | 100   |

Теперь я хочу выбрать 2 лучших ученика в CS классе CS.201 в 2016.Spring, поэтому результаты могут выглядеть следующим образом:

| student_id | major | semester    | course | grade |
|------------|-------|-------------|--------|-------|
| 1001       | CS    | 2016.Spring | CS.201 | 100   |
| 1003       | CS    | 2016.Spring | CS.201 | 99    |
| 1004       | CS    | 2016.Spring | CS.201 | 99    |

Обратите внимание, что, поскольку 2 студента получили 99 в CS.201, поэтому нам нужны все 3 записи (не только с использованием limit(2)).

База данных MySQL.

Мой скрипт sql выглядит так:

SELECT student_info.student_id, 
               student_info.major, 
               student_grade.semester, 
               student_grade.course, 
               student_grade.grade
FROM student_info, student_grade
WHERE student_info.major = 'CS'
  AND student_info.student_id = student_grade.student_id
  AND student_grade.semester = '2016.Spring'
  AND student_grade.course = 'CS.201'
ORDER BY student_grade.grade DESC
LIMIT 2

Ответы [ 2 ]

0 голосов
/ 25 апреля 2018

Вы можете попробовать mysql window function с DENSE_RANK(). С документацией можно ознакомиться здесь .

SELECT * FROM
(
    SELECT
        a.*,
        DENSE_RANK() OVER w AS 'rank'
    FROM

    (
        SELECT
            g.student_id,
            i.major,
            g.course,
            g.semester,
            g.grade
        FROM 
            student_grade g
            JOIN student_info i
                ON i.student_id = g.student_id

        WHERE i.major = 'CS'
            AND g.semester = '2016.Spring'
            AND g.course = 'CS.201'
    ) a

    WINDOW w AS (ORDER BY a.grade DESC)
) b

WHERE b.rank <= 2;

Надеюсь, это поможет, удачи!

0 голосов
/ 25 апреля 2018

Вопрос должен использовать функцию DENSE_RANK, к сожалению, DENSE_RANK функция поддерживает только версию выше, чем MySQL 8.0 .

Вам нужно сделать rank на student_grade, так что вы можете написать подзапрос для создания набора результатов ранга, затем join для student_info

SELECT b.student_id, 
       b.major, 
       a.semester, 
       a.course, 
       a.grade 
FROM   (SELECT student_id, 
               grade, 
               semester, 
               course, 
               @prev := @curr, 
               @curr := grade, 
               @rank := IF(@prev = @curr, @rank, @rank + 1) AS rank 
        FROM   student_grade, 
               (SELECT @curr := NULL, 
                       @prev := NULL, 
                       @rank := 0) s 
        WHERE  course = 'CS.201' 
               AND semester = '2016.Spring' 
        ORDER  BY grade DESC) a 
       INNER JOIN student_info b 
               ON a.student_id = b.student_id 
WHERE  a.rank <= 2 
       AND b.major = 'CS' 

sqlfiddle: https://www.db -fiddle.com / f / tkU4UfRE3AZziiEn4HiLwF / 0

Объяснение:

  • @prev := @curr пусть @curr будет предыдущим классом
  • @curr := grade установить токоценка в переменной @curr
  • @rank := IF(@prev = @curr, @rank, @rank+1) AS rank для проверки @prev переменная и @curr переменная совпадают. если они одинаковы, используются одинаково rank в противном случае rank + 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...