如何在子查询中 select 多个值,但将每个值分配给匹配的父 select 值?
How to select multiple values in a subquery but have each value assigned to matching parent select value?
抱歉,问题罗嗦。我有一个从 User table 中提取数据的查询,我想从 [ 中提取 completionstatecourse_modules_completion table 对于每个用户和课程中的每个 activity。我无法将来自各种 table 的多个值链接到每行的一个用户。
我能够从 User table 那里获得我想要的信息就好了。然后我加入多个 table,以便能够从 course_modules_completion table 中提取完成状态字段。我需要做的是为每个用户提取课程中每个 activity 对应的 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 值的子查询,但它返回多行,因此出现错误。
此外,我想将 completionstate 列中的值显示为文本。该列中有四个值:0、1、2、3,我想做的是将每个值转换为 "Not seen"、"Seen"、"Completed and passed" 和 "Completed and failed"分别
因为我是 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
你还应该按 u.id
而不是 u.username
分组。这将允许您 select 在功能上依赖于此主键的其他列,而无需使用聚合函数。
抱歉,问题罗嗦。我有一个从 User table 中提取数据的查询,我想从 [ 中提取 completionstatecourse_modules_completion table 对于每个用户和课程中的每个 activity。我无法将来自各种 table 的多个值链接到每行的一个用户。
我能够从 User table 那里获得我想要的信息就好了。然后我加入多个 table,以便能够从 course_modules_completion table 中提取完成状态字段。我需要做的是为每个用户提取课程中每个 activity 对应的 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 值的子查询,但它返回多行,因此出现错误。
此外,我想将 completionstate 列中的值显示为文本。该列中有四个值:0、1、2、3,我想做的是将每个值转换为 "Not seen"、"Seen"、"Completed and passed" 和 "Completed and failed"分别
因为我是 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
你还应该按 u.id
而不是 u.username
分组。这将允许您 select 在功能上依赖于此主键的其他列,而无需使用聚合函数。