----------------------
id | name
______________________
1 | Name 1
2 | Name 2
id | student_id | ctype | level
__________________________________
1 | 2 | beginner | complete
2 | 2 | advanced | current
3 | 1 | beginner | current
4 | 2 | intermed | skipped
从上面的两个表中,我试图根据课程表中的级别获取最新的用户记录。该级别应该匹配,以便它以相同的顺序检查当前,完成和跳过,因此如果用户具有任何课程类型的当前级别,则应该提取它,否则检查级别完成...
我正在使用以下查询。
SELECT `sc`.`student_id`,
`s`.`name`,
`sc`.`id` as `course_id`,
`sc`.`ctype`,
`sc`.`level`,
FROM `course` `sc`
LEFT JOIN `students` `s` ON `s`.`id` = `sc`.`student_id`
WHERE sc.id = (SELECT ssc.id FROM course ssc WHERE ssc.student_id = sc.student_id
ORDER BY FIELD(`ssc`.`level`,"current","complete","skipped") DESC LIMIT 1,1)
GROUP BY `sc`.`student_id`
ORDER BY `sc`.`id` DESC
LIMIT 20
上述查询的问题是,只有在课程表中有多个匹配的用户ID时才会显示。所以我得到的最终输出是它只显示id为2的学生,并忽略id为1的学生,因为不超过一个。
student_id | name | course_id | ctype | level |
=====================================================
2 | Name 2 | 2 | advanced | current
student_id | name | course_id | ctype | level |
=====================================================
2 | Name 2 | 2 | advanced | current
1 | Name 1 | 3 | beginner | current
注意:我也尝试过FIELD_IN_SET和IN而不是FIELD im获得相同的结果
答案 0 :(得分:1)
将LIMIT 1,1
更改为LIMIT 0,1
或仅LIMIT 1
。
与SQL中的大多数其他内容不同,offset
子句中的LIMIT
字段是基于0的,而不是基于1的。因此,如果只有一个匹配的行,LIMIT 1,1
会跳过它。如果有2个或更多匹配的行,则表示您没有获得最高匹配,您将获得第2场比赛。
此外,排序应为ASC
,而不是DESC
,因为您希望选择最低字段(current
),而不是最高字段。
SELECT `sc`.`student_id`,
`s`.`name`,
`sc`.`id` as `course_id`,
`sc`.`ctype`,
`sc`.`level`
FROM `course` `sc`
LEFT JOIN `students` `s` ON `s`.`id` = `sc`.`student_id`
WHERE sc.id = (
SELECT ssc.id FROM course ssc
WHERE ssc.student_id = sc.student_id
ORDER BY FIELD(`ssc`.`level`,"current","complete","skipped") ASC
LIMIT 0,1)
GROUP BY `sc`.`student_id`
ORDER BY `sc`.`id` DESC
LIMIT 20
也不需要GROUP BY
sc .
student_id`。查询只返回每个学生一个课程ID,因此每个学生不能有多行。