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

优雅获取Sally的一、二、三度关联学生的SQL实现方案

Clean Recursive CTE for 1st, 2nd, and 3rd-Degree Student Course Connections

Instead of cobbling together multiple separate CTEs, a recursive CTE is the elegant solution here. It lets you traverse the student-course network in one reusable query, making it easier to maintain and extend if you ever need to add more connection degrees later.

How It Works:

First, we start with Sally's student ID (we know it's 2 from the student table). The recursive CTE will:

  • Track each connected student's ID
  • Label their connection degree (1 = directly shares a course with Sally, 2 = shares with a 1st-degree student, etc.)
  • Keep a path of connections to avoid cycles (so we don't end up with duplicate entries for students connected through multiple paths)

The Query:

WITH RECURSIVE student_links AS (
    -- Anchor: 1st-degree connections (students sharing courses with Sally)
    SELECT 
        si.student_id AS student_id,
        1 AS degree,
        CONCAT('2->', si.student_id) AS connection_path
    FROM students_in si
    WHERE si.course_id IN (SELECT course_id FROM students_in WHERE student_id = 2)
      AND si.student_id != 2 -- Don't include Sally herself
    UNION ALL
    -- Recursive step: Find next-degree connections
    SELECT 
        si.student_id,
        sl.degree + 1,
        CONCAT(sl.connection_path, '->', si.student_id)
    FROM student_links sl
    -- Join to find courses taken by the current linked student
    JOIN students_in shared_courses ON shared_courses.student_id = sl.student_id
    -- Find other students taking those courses
    JOIN students_in si ON si.course_id = shared_courses.course_id
    WHERE si.student_id != 2 -- Skip Sally
      -- Avoid cycles: don't re-add students already in the connection path
      AND NOT sl.connection_path LIKE CONCAT('%->', si.student_id, '%')
      -- Stop at 3rd-degree connections
      AND sl.degree < 3
)
-- Final output: Get unique students, their names, and clarify their connection
SELECT DISTINCT
    sl.student_id,
    s.name AS student_name,
    CASE
        WHEN sl.degree = 1 THEN 
            CONCAT('took course ID ', GROUP_CONCAT(DISTINCT c.course_id SEPARATOR ', '), ' with Sally')
        WHEN sl.degree = 2 THEN
            CONCAT('took course ID ', GROUP_CONCAT(DISTINCT c.course_id SEPARATOR ', '), ' with ', (SELECT name FROM student WHERE id = SUBSTRING_INDEX(sl.connection_path, '->', -2)))
        WHEN sl.degree = 3 THEN
            CONCAT('took course ID ', GROUP_CONCAT(DISTINCT c.course_id SEPARATOR ', '), ' with ', (SELECT name FROM student WHERE id = SUBSTRING_INDEX(sl.connection_path, '->', -2)))
    END AS connection_note
FROM student_links sl
JOIN student s ON s.id = sl.student_id
-- Join to get the shared course(s) for the connection note
JOIN students_in si ON si.student_id = sl.student_id
JOIN course c ON c.course_id = si.course_id
-- Filter to only courses that link them to the previous degree student
WHERE (
    sl.degree = 1 AND c.course_id IN (SELECT course_id FROM students_in WHERE student_id = 2)
    OR sl.degree > 1 AND c.course_id IN (SELECT course_id FROM students_in WHERE student_id = SUBSTRING_INDEX(sl.connection_path, '->', -2))
)
GROUP BY sl.student_id, s.name, sl.degree, sl.connection_path
ORDER BY sl.degree, sl.student_id;

Why This Beats Multiple CTEs:

  • Less Redundancy: No need to rewrite similar logic for each degree—just adjust the sl.degree < 3 condition if you want to go to 4th degree or more.
  • Cycle Protection: The connection_path ensures we don't loop infinitely or count the same student multiple times for different paths.
  • Clearer Logic: The recursive structure mirrors how the connections actually form, making it easier to debug or modify later.

Output Matching Your Expectations:

student_idstudent_nameconnection_note
12Sydneytook course ID 3 with Sally
17Roberttook course ID 3 with Sally
41Jamestook course ID 3, 212 with Sally
1Bobtook course ID 4 with James
92Doristook course ID 12 with James
22Williamtook course ID 102 with Bob

(Note: Your expected result had a typo where William's student ID was listed as 102—this query returns the correct ID 22 as per the student table.)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 10:22:54