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

MySQL多表查询:获取成员课程偏好及指定课程首选教员

解决课程任教成员列表及首选教员的查询方案

嘿,我来帮你搞定这个查询需求!首先得明确一个关键前提:虽然你只给出了Members表的部分数据,但要实现「职称更高者为首选教员」的规则,Members表必须包含职称字段(比如Title,用来区分教授、副教授、讲师这类层级)。接下来我会用MySQL为例,一步步拆解实现逻辑,其他数据库(比如PostgreSQL、SQL Server)的思路类似,只是部分函数语法有差异。

先明确表结构假设

首先补全Members表的完整结构(你可以根据实际情况调整字段名):

CREATE TABLE Members (
    MemberName VARCHAR(50), -- 对应你的Member Name
    Preferences VARCHAR(100), -- 逗号分隔的偏好课程
    Title VARCHAR(20) -- 职称字段,比如'Professor' > 'Associate Professor' > 'Lecturer'
);

核心实现步骤

1. 拆分逗号分隔的偏好课程

Members表的Preferences是逗号拼接的字符串,我们需要把它拆成「每个成员-单个课程」的行数据,这样才能按课程分组处理。

2. 给每个课程的成员按职称排序

用窗口函数给每个课程下的成员按职称优先级排序,职称最高的成员排名为1。

3. 聚合生成最终结果

把每个课程的所有任教成员拼接成列表,同时取排名第一的成员作为首选教员。

完整查询语句

WITH SplitCourses AS (
    -- 第一步:拆分偏好课程,每个成员对应一行课程
    SELECT 
        m.MemberName,
        -- 修剪课程代码前后的空格(防止数据里有多余空格)
        TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(m.Preferences, ',', n.n), ',', -1)) AS CourseCode,
        m.Title
    FROM Members m
    -- 生成数字序列,用来拆分逗号分隔的字符串(这里假设最多3个课程,可按需扩展)
    JOIN (SELECT 1 AS n UNION ALL SELECT 2 UNION ALL SELECT 3) n 
        ON CHAR_LENGTH(m.Preferences) - CHAR_LENGTH(REPLACE(m.Preferences, ',', '')) >= n.n - 1
),
RankedMembers AS (
    -- 第二步:给每个课程的成员按职称排序,职称越高排名越靠前
    SELECT 
        CourseCode,
        MemberName,
        Title,
        ROW_NUMBER() OVER (
            PARTITION BY CourseCode 
            ORDER BY 
                -- 这里定义职称优先级,你可以根据实际职称调整顺序
                CASE Title 
                    WHEN 'Professor' THEN 1 
                    WHEN 'Associate Professor' THEN 2 
                    WHEN 'Lecturer' THEN 3 
                    ELSE 4 
                END ASC
        ) AS RankNum
    FROM SplitCourses
)
-- 第三步:聚合生成最终结果
SELECT 
    rc.CourseCode AS `Course-Code`,
    -- 拼接所有愿意任教的成员,按名字排序
    GROUP_CONCAT(DISTINCT sc.MemberName ORDER BY sc.MemberName SEPARATOR ',') AS `Willing Members`,
    rc.MemberName AS Preferred
FROM SplitCourses sc
-- 关联排名第一的成员作为首选
JOIN RankedMembers rc ON sc.CourseCode = rc.CourseCode AND rc.RankNum = 1
GROUP BY rc.CourseCode, rc.MemberName
-- 可选:过滤你示例里的目标课程,去掉WHERE则查询所有课程
WHERE rc.CourseCode IN ('CS201', 'CS304');

针对不同数据库的适配说明

  • PostgreSQL:拆分用unnest(string_to_array(m.Preferences, ',')),聚合用STRING_AGG(sc.MemberName, ',' ORDER BY sc.MemberName)代替GROUP_CONCAT。
  • SQL Server:拆分用STRING_SPLIT(m.Preferences, ','),聚合用STRING_AGG(sc.MemberName, ',') WITHIN GROUP (ORDER BY sc.MemberName)。

关键逻辑说明

示例结果中CS201的首选是Neo,CS304的首选是Jhon,这是因为在职称排序规则里,他们的职称比同课程的其他成员更高(比如Neo是教授,Jhon Doe和Jhon是讲师;Jhon是教授,其他两人是讲师)。你只需要调整CASE Title里的优先级顺序,就能匹配你的实际职称体系。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:01:32