You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL如何按首字符筛选去重 获取不带分节的主课程记录

Moodle主课程记录查询实现方案

需求说明

提取课程数据时,课程下设有A、B等多个分节,仅需查询不带分节标识的主课程记录。参考示例列表规则,主课程排在列表末尾,分节课程排列在主课程上方,本次目标获取的主课程记录值为1 / 4 / C-501 / Matematicas Aplicadas I / C-501。

现有方案问题

此前尝试DISTINCT LEFT(mc.shortname,5)、substr(mc.shortname,1,5)写法未生效,核心原因是这类写法仅对shortname字段做截断展示,没有做行级过滤;就算修正DISTINC的拼写错误,也无法达到过滤效果——不同分节课程的ID、学分、全名等字段值均不相同,最终还是会返回所有分节课程的完整信息。
当前使用的基础查询语句如下:

SELECT mc.id, 
(SELECT mcd.value from mdl_customfield_data mcd WHERE mcd.fieldid =5 AND mc.id = mcd.instanceid) tipo_curso, 
mcd.value creditos, 
mc.fullname, 
mc.shortname
FROM mdl_course mc,mdl_customfield_data mcd
WHERE mc.category = 10
AND mc.id = mcd.instanceid
AND mcd.fieldid = 1;

参考示例截图:
课程列表示例

可直接使用的正确查询语句

主课程与分节课程的核心区分规则:分节课程的shortname会在主课程编码后追加A/B等分节标识,主课程的shortname无额外后缀,同分类下不存在其他课程的shortname是它的前缀且长度更短。通过NOT EXISTS做行级过滤即可精准拿到主课程记录,不需要硬编码编码截断长度,适配不同长度的课程编码规则:

SELECT 
  mc.id, 
  (SELECT mcd.value from mdl_customfield_data mcd WHERE mcd.fieldid =5 AND mc.id = mcd.instanceid) tipo_curso, 
  mcd.value creditos, 
  mc.fullname, 
  mc.shortname
FROM mdl_course mc
INNER JOIN mdl_customfield_data mcd 
  ON mc.id = mcd.instanceid
  AND mcd.fieldid = 1
WHERE mc.category = 10
AND NOT EXISTS (
  SELECT 1 
  FROM mdl_course mc2 
  WHERE mc2.category = 10
  AND mc.shortname LIKE CONCAT(mc2.shortname, '%')
  AND LENGTH(mc2.shortname) < LENGTH(mc.shortname)
)

逻辑说明

  • 将原语句的隐式逗号关联改为显式INNER JOIN,关联逻辑更清晰,避免漏写关联条件出现笛卡尔积
  • NOT EXISTS子句逐行校验:如果同分类下存在另一条课程记录,它的shortname是当前课程shortname的前缀且长度更短,说明当前记录是分节课程,直接排除;最终保留的就是无分节后缀的主课程
  • 不依赖固定的编码长度,就算后续课程编码规则调整,语句也能正常生效

内容的提问来源于stack exchange,提问作者user8282183292

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 01:31:18