我有以下(简化)查询:
SELECT
u.idnumber AS user_idnumber,
sst_status.value AS scorm_status,
sst_starttime.value AS scorm_starttime,
sst_duration.value AS scorm_duration,
sst_score.value AS scorm_score,
u.id as uid,
s.id as scormid,
ss.id as ssid
FROM {user} u
LEFT JOIN {prog_user_assignment} prua ON prua.userid = u.id
LEFT JOIN {prog} pr ON prua.programid = pr.id
LEFT JOIN {prog_courseset} prcs ON prcs.programid = pr.id
LEFT JOIN {prog_courseset_course} prcsc ON prcsc.coursesetid = prcs.id
LEFT JOIN {course} c ON prcsc.courseid = c.id
LEFT JOIN {scorm} s ON s.id = cm.instance
LEFT JOIN {scorm_scoes} ss ON ss.scorm = s.id
LEFT JOIN {scorm_scoes_track} sst_status
ON sst_status.userid = u.id
AND sst_status.scormid = ss.scorm
AND sst_status.element = 'cmi_core.lesson_status'
AND sst_status.scoid = ss.id
LEFT JOIN {scorm_scoes_track} sst_starttime
ON sst_starttime.userid = u.id
AND sst_starttime.scormid = ss.scorm
AND sst_starttime.element = 'x.start.time'
AND sst_starttime.scoid = ss.id
LEFT JOIN {scorm_scoes_track} sst_duration
ON sst_duration.userid = u.id
AND sst_duration.scormid = ss.scorm
AND sst_duration.element = 'cmi.core.total_time'
AND sst_duration.scoid = ss.id
LEFT JOIN {scorm_scoes_track} sst_score
ON sst_score.userid = u.id
AND sst_score.scormid = ss.scorm
AND sst_score.element = 'cmi.core.score.raw'
AND sst_score.scoid = ss.id
WHERE u.id IN([SOME_EXAMPLE_IDS_HERE]) AND u.deleted = 0
group by u.idnumber, c.id
现在问题是没有GROUP BY子句,一些记录具有scorm_status,scorm_starttime等的值。但是,这些包含重复项。但是,使用group by语句,仅为这些列返回NULL值。有没有人知道如何解决这个问题?
答案 0 :(得分:0)
以下是您查询的简化版本:
select u.idnumber AS user_idnumber, sst_status.value AS scorm_status,
sst_starttime.value AS scorm_starttime, sst_duration.value AS scorm_duration,
sst_score.value AS scorm_score, u.id as uid, s.id as scormid, ss.id as ssid
. . .
group by u.idnumber, c.id;
您会注意到select
中的大多数列都不在group by
中。这是使用MySQL的(错误)功能,通常不允许在其他数据库中使用。
MySQL所做的是从结果中的一行中选择 abritrary 值。我们的想法是,如果group
的列是常量,这可以很好地工作。但是,在其他情况下,它通常不会像预期的那样起作用。
如果您想要非NULL值,则可以使用max()
或min()
来获取最大值或最小值。
例如:
min(sst_status.value) AS scorm_status
等等。
答案 1 :(得分:0)
使用GROUP_CONCAT和SUBSTRING_INDEX: -
SELECT
u.idnumber AS user_idnumber,
SUBSTRING_INDEX(GROUP_CONCAT(sst_status.value), ',', 1) AS scorm_status,
SUBSTRING_INDEX(GROUP_CONCAT(sst_starttime.value), ',', 1) AS scorm_starttime,
SUBSTRING_INDEX(GROUP_CONCAT(sst_duration.value), ',', 1) AS scorm_duration,
SUBSTRING_INDEX(GROUP_CONCAT(sst_score.value), ',', 1) AS scorm_score,
u.id as uid,
s.id as scormid,
ss.id as ssid
FROM {user} u
LEFT JOIN {prog_user_assignment} prua ON prua.userid = u.id
LEFT JOIN {prog} pr ON prua.programid = pr.id
LEFT JOIN {prog_courseset} prcs ON prcs.programid = pr.id
LEFT JOIN {prog_courseset_course} prcsc ON prcsc.coursesetid = prcs.id
LEFT JOIN {course} c ON prcsc.courseid = c.id
LEFT JOIN {scorm} s ON s.id = cm.instance
LEFT JOIN {scorm_scoes} ss ON ss.scorm = s.id
LEFT JOIN {scorm_scoes_track} sst_status
ON sst_status.userid = u.id
AND sst_status.scormid = ss.scorm
AND sst_status.element = 'cmi_core.lesson_status'
AND sst_status.scoid = ss.id
LEFT JOIN {scorm_scoes_track} sst_starttime
ON sst_starttime.userid = u.id
AND sst_starttime.scormid = ss.scorm
AND sst_starttime.element = 'x.start.time'
AND sst_starttime.scoid = ss.id
LEFT JOIN {scorm_scoes_track} sst_duration
ON sst_duration.userid = u.id
AND sst_duration.scormid = ss.scorm
AND sst_duration.element = 'cmi.core.total_time'
AND sst_duration.scoid = ss.id
LEFT JOIN {scorm_scoes_track} sst_score
ON sst_score.userid = u.id
AND sst_score.scormid = ss.scorm
AND sst_score.element = 'cmi.core.score.raw'
AND sst_score.scoid = ss.id
WHERE u.id IN([SOME_EXAMPLE_IDS_HERE]) AND u.deleted = 0
group by u.idnumber, c.id
这是获取这些字段的第一个非空值。请注意,这依赖于不包含逗号的字段(但很容易为GROUP_CONCAT指定不同的分隔符)。如果需要,您可以指定GROUP_CONCAT的订单以获取您的首选值。