mysql - 如何在子查询中选择多个值,但将每个值分配给匹配的父选择值?
问题描述
抱歉,问题的罗嗦混乱。我有一个从User表中提取数据的查询,我想从course_modules_completion表中为每个用户和课程中的每个活动提取完成状态。我无法将来自不同表的多个值链接到每行的用户。
我能够从User表中获得我想要的信息。然后我加入多个表,以便能够从 course_modules_completion 表中提取 completionstate 字段。我需要做的是为每个用户提取与课程中每个活动相对应的完成状态的值。
SELECT u.username AS 'ID'
,u.firstname AS 'Names'
,u.lastname AS 'Lastnames'
,(SELECT completionstate FROM prefix_course_modules_completion cmc
INNER JOIN prefix_user u ON cmc.userid = u.id
INNER JOIN prefix_course_modules cm ON cmc.coursemoduleid = cm.id
INNER JOIN prefix_course c ON cm.course = c.id
INNER JOIN prefix_resource r ON c.id = r.course
WHERE (r.id = 6) AND (c.id = 5)
) AS 'Activity 1'
FROM prefix_user u LEFT JOIN prefix_grade_grades g ON u.id = g.userid
INNER JOIN prefix_course_modules_completion cmc ON cmc.userid = u.id
INNER JOIN prefix_course_modules cm ON cmc.coursemoduleid = cm.id
INNER JOIN prefix_course c ON cm.course = c.id
INNER JOIN prefix_resource r ON c.id = r.course
WHERE (u.id > 7) AND (u.firstaccess > 0) AND (c.id = 5)
GROUP BY u.username
ORDER BY u.firstname ASC
我所期望的是这样的:
ID - Name - Last name - Email - Activity 1 - Activity 2 - Test
382 - John - Johnson - email@e.com - Seen - Not seen - Failed
17 - Mark - Markson - email2@e.com - Seen - Seen - Passed
相反,我得到的是同一用户的多行,它们具有所需的值或所有用户所需的相同值,就好像它对用户没有任何区别一样。正如您在上面的代码中看到的那样,我尝试使用仅针对完成状态值的子查询,但它返回多行,因此出现错误。
此外,我想将completionstate列中的值显示为文本。该列中有四个值:0、1、2、3,我想做的是将每个值分别转换为“未看到”、“已看到”、“完成并通过”和“完成并失败”。
因为我是 SQL 的初学者,所以我无法确定我的问题是由于逻辑错误、编码错误还是两者兼而有之。
编辑:稍微修剪一下代码以使这个问题更简单。
解决方案
你想要做的是一种枢轴,所以你可以在没有相关子查询的情况下做到这一点。
SELECT u.username AS 'ID'
,u.firstname AS 'Names'
,u.lastname AS 'Lastnames'
,u.email AS 'Email'
,c.fullname AS 'Course'
,(LEFT(g.finalgrade,2)) AS 'Final grade'
,ELT(MAX(IF(r.id = 6, completion_state, NULL))+1,
'Not seen', 'Seen', 'Completed and passed', 'Completed and failed') AS `Activity 1`
,ELT(MAX(IF(r.id = 7, completion_state, NULL))+1,
'Not seen', 'Seen', 'Completed and passed', 'Completed and failed') AS `Activity 2`
,ELT(MAX(IF(r.id = 8, completion_state, NULL))+1,
'Not seen', 'Seen', 'Completed and passed', 'Completed and failed') AS `Activity 3`
FROM prefix_user u LEFT JOIN prefix_grade_grades g ON u.id = g.userid
INNER JOIN prefix_course_modules_completion cmc ON cmc.userid = u.id
INNER JOIN prefix_course_modules cm ON cmc.coursemoduleid = cm.id
INNER JOIN prefix_course c ON cm.course = c.id
INNER JOIN prefix_resource r ON c.id = r.course
WHERE (u.id > 7) AND (u.firstaccess > 0) AND (c.id = 5)
GROUP BY u.id
ORDER BY u.firstname ASC
yu 也应该 group byu.id
而不是u.username
。这将允许您选择在功能上依赖于此主键的其他列,而无需使用聚合函数。
推荐阅读
- javascript - 在nodejs typescript app中使用默认值从类中创建新对象?
- bash - BASH 增加 MAC 地址
- firefox - SMIL 动画不适用于 Firefox 上的 use 元素
- c++ - 下面的表达式是做什么的:x = (a1,a2,...,n);
- angular - 将日期前一天传递并保存到服务器的时刻
- android - 为什么 JobScheduler 没有按预期工作
- oracle - 从包中授予/撤销对过程的执行权限
- c++ - 如何将类的自定义数据传递给窗口回调而不将其声明为静态?
- php - 获取列的总和
- sql-server - 如何找到我的程序中没有调用 sql server 中的哪些 sql 类型?