【问题标题】:Oracle query to group multi level many to many relationships into independent groups [closed]Oracle查询将多级多对多关系分组为独立组[关闭]
【发布时间】:2021-02-28 23:45:57
【问题描述】:

基于对学生和学科交叉引用的多级 MANY TO MANY 依赖,如何形成 ORACLE sql/plsql 查询对 Student_Subject 表进行 GROUP,从而使组独立且排他如下?我在实际表中有 519 行。我正在寻找一个高性能的解决方案

示例源表:

预期目标输出:

实际源表数据创建查询

CREATE TABLE student_subject ( student_name, subject_name ) AS
 SELECT 'SMITH', 'CHEMISTRY' FROM DUAL UNION ALL
 SELECT 'ROBIN', 'PHYSICS' FROM DUAL UNION ALL
 SELECT 'SAM', 'PHYSICS' FROM DUAL UNION ALL
 SELECT 'SAM', 'MATH' FROM DUAL UNION ALL
 SELECT 'JENNY', 'MATH' FROM DUAL UNION ALL
 SELECT 'JENNY', 'ACCOUNTS' FROM DUAL UNION ALL
 SELECT 'DON', 'ENGLISH' FROM DUAL UNION ALL
 SELECT 'DON', 'SPANISH' FROM DUAL UNION ALL
 SELECT 'RON', 'HISTORY' FROM DUAL UNION ALL
 SELECT 'JOVAN', 'HISTORY' FROM DUAL UNION ALL
 -- etc. for an additional 509 more rows

this dbfiddle for a sample set of 475 rows

【问题讨论】:

  • 组是如何定义的?是否有一栏表明学生/科目所在的组?如果没有这些信息,就无法以您请求的格式拆分数据。例如,为什么史密斯/化学在第 1 组而不在第 4 组?
  • 请不要删除问题,过几天再重新提问。
  • @EJEgyed 看起来小组是基于学生之间的间接关系。例如,Robin 和 Sam 一起学习物理,Sam 和 Jenny 一起学习数学。因此,所有 Robin、Sam 和 Jenny 记录都在同一个组中。
  • @MatthewMcPeak:听起来不错。但是,要使这个问题成为主题,它至少需要明确指定。
  • 供将来参考:不要尝试将 500 多行放入一个问题中。根本没有必要这样做,您只需要几个示例行来说明更大的问题。如果你必须包含一个更大的集合,你总是可以引用一个 dbfiddle。我已将您的数据集移至一个;你只设法放入 475 行,所以这就是我们可以使用的。或者您可以使用dataset from your deleted question,它略有不同,包含 518 行。

标签: sql oracle plsql many-to-many hierarchy


【解决方案1】:

我正在寻找一个高效的解决方案

如果你想要高性能,那么就别想SQL了。使用您的(高度连接的)数据,没有办法使用CONNECT BY 技巧,它不会查看大量额外的、不必要的数据。

这是一个简单的 PL/SQL 块,它可以很快完成。到目前为止,我相信比纯 SQL 更快。 (像往常一样,如果这意味着要学习新东西,我会很高兴地吃乌鸦……)

这通过从尚未分配给组的行中查找具有最低subject_name 的记录来工作。这些获得分配的下一个组号。然后,我们无限循环地寻找与新组中的行直接相关的行并将它们分配给新组。当我们找不到更多直接相关的行时,该组就完成了,我们开始下一个组。当我们无法创建任何新组时,我们就完成了。

-- Add a column to student_subject to hold the group number results
ALTER TABLE student_subject ADD ( group_number NUMBER );

-- Let's time it...
SET TIMING ON

-- Go through and assign group numbers to each record.
-- Doing it iteratively in PL/SQL means we can easily look at each row only once.
BEGIN

  UPDATE student_subject SET group_number = null;
  
  LOOP
    UPDATE student_subject ss
    SET group_number = ( SELECT nvl(max(group_number),0)+1 FROM student_subject ss2 )  -- Assign next group number
    WHERE subject_name = ( SELECT min(subject_name) FROM student_subject ss2 WHERE group_number IS NULL );
    
    EXIT WHEN SQL%ROWCOUNT = 0;  -- done..  all rows have groups now.
  
    LOOP
      UPDATE student_subject ss
      SET group_number = ( SELECT max(group_number) FROM student_subject ss2 )
      WHERE group_number is null
      AND EXISTS ( SELECT 'direct relation' FROM student_subject ss2 WHERE (ss2.subject_name = ss.subject_name OR ss2.student_name = ss.student_name ) AND ss2.group_number = ( SELECT max(group_number) FROM student_subject ss3 ) );
      
      EXIT WHEN SQL%ROWCOUNT = 0;  -- finished group.  move to next group
    END LOOP;
  END LOOP;

END;
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.128

您可以通过将更新中的 (SELECT... 表达式替换为 PL/SQL 变量来进一步优化它。例如,跟踪当前组号,而不是每次都选择MAX()。我只是懒惰。

【讨论】:

    【解决方案2】:

    您可以使用 PL/SQL 管道函数:

    如果您创建类型:

    CREATE TYPE ssg_obj AS OBJECT (
      student_name VARCHAR2(100),
      subject_name VARCHAR2(100),
      grp          NUMBER(8,0)
    );
    
    CREATE TYPE ssg_tbl AS TABLE OF ssg_obj;
    

    那么你可以使用:

    CREATE FUNCTION get_student_subject_groups RETURN ssg_tbl PIPELINED
    IS
      TYPE stud_tbl IS TABLE OF STUDENT_SUBJECT.STUDENT_NAME%TYPE;
      TYPE subj_tbl IS TABLE OF STUDENT_SUBJECT.SUBJECT_NAME%TYPE;
      
      ssgs ssg_tbl;
      t_found_students stud_tbl;
      t_found_subjects subj_tbl;
      v_grp            PLS_INTEGER := 0;
      v_min_idx        PLS_INTEGER := 0;
      v_found          BOOLEAN;
      v_match_subj     BOOLEAN;
      v_match_stud     BOOLEAN;
    BEGIN
      SELECT ssg_obj( student_name, subject_name, 0 )
      BULK COLLECT INTO ssgs
      FROM   student_subject;
      
      LOOP
        v_grp := v_grp + 1;
        v_found := FALSE;
    
        FOR i IN v_min_idx + 1 .. ssgs.COUNT LOOP
          IF ssgs(i).grp = 0 THEN
            v_min_idx := i;
            ssgs(i).grp := v_grp;
            PIPE ROW( ssgs(i) );
            t_found_students := stud_tbl( ssgs(i).student_name );
            t_found_subjects := subj_tbl( ssgs(i).subject_name );
            v_found := TRUE;
            EXIT;
          END IF;
        END LOOP;
        EXIT WHEN NOT v_found;
        
        LOOP
          v_found := FALSE;
          FOR i IN v_min_idx + 1 .. ssgs.COUNT LOOP
            IF ssgs(i).grp > 0 THEN
              CONTINUE;
            END IF;
            v_match_subj := ssgs(i).subject_name MEMBER OF t_found_subjects;
            v_match_stud := ssgs(i).student_name MEMBER OF t_found_students;
            IF v_match_subj OR v_match_stud THEN
              ssgs(i).grp := v_grp;
              PIPE ROW( ssgs(i) );
              IF NOT v_match_subj THEN
                t_found_subjects.EXTEND;
                t_found_subjects(t_found_subjects.COUNT) := ssgs(i).subject_name;
                v_found := TRUE;
              END IF;
              IF NOT v_match_stud THEN
                t_found_students.EXTEND;
                t_found_students(t_found_students.COUNT) := ssgs(i).student_name;
                v_found := TRUE;
              END IF;
            END IF;
          END LOOP;
          EXIT WHEN NOT v_found;
        END LOOP;
      END LOOP;
    END;
    /
    

    然后:

    SELECT *
    FROM   TABLE( get_student_subject_groups() )
    

    输出(用于您的大样本数据):

    STUDENT_NAME | SUBJECT_NAME                       | GRP
    :----------- | :--------------------------------- | --:
    LIAM         | ACCOUNTING                         | 1
    NOAH         | ACCOUNTING                         | 1
    OLIVER       | ACCOUNTING                         | 1
    WILLIAM      | ACCOUNTING                         | 1
    ELIJAH       | ACCOUNTING                         | 1
    JAMES        | ACCOUNTING                         | 1
    BENJAMIN     | ACCOUNTING                         | 1
    LUCAS        | ACCOUNTING                         | 1
    MASON        | ACCOUNTING                         | 1
    LIAM         | BUSINESS_LAW                       | 1
    NOAH         | BUSINESS_LAW                       | 1
    WILLIAM      | BUSINESS_LAW                       | 1
    ELIJAH       | BUSINESS_LAW                       | 1
    ETHAN        | BUSINESS_LAW                       | 1
    ALEXANDER    | BUSINESS_LAW                       | 1
    HENRY        | BUSINESS_LAW                       | 1
    JACOB        | BUSINESS_LAW                       | 1
    MICHAEL      | BUSINESS_LAW                       | 1
    DANIEL       | BUSINESS_LAW                       | 1
    LOGAN        | BUSINESS_LAW                       | 1
    JACKSON      | BUSINESS_LAW                       | 1
    SEBASTIAN    | BUSINESS_LAW                       | 1
    JACK         | BUSINESS_LAW                       | 1
    AIDEN        | BUSINESS_LAW                       | 1
    OWEN         | BUSINESS_LAW                       | 1
    SAMUEL       | BUSINESS_LAW                       | 1
    MATTHEW      | BUSINESS_LAW                       | 1
    JOSEPH       | BUSINESS_LAW                       | 1
    NOAH         | BUSINESS_MANAGEMENT                | 1
    OLIVER       | BUSINESS_MANAGEMENT                | 1
    WILLIAM      | BUSINESS_MANAGEMENT                | 1
    ELIJAH       | BUSINESS_MANAGEMENT                | 1
    LEVI         | BUSINESS_MANAGEMENT                | 1
    BENJAMIN     | BUSINESS_MANAGEMENT                | 1
    LUCAS        | BUSINESS_MANAGEMENT                | 1
    MATEO        | BUSINESS_MANAGEMENT                | 1
    DAVID        | BUSINESS_MANAGEMENT                | 1
    ETHAN        | BUSINESS_MANAGEMENT                | 1
    ALEXANDER    | BUSINESS_MANAGEMENT                | 1
    HENRY        | BUSINESS_MANAGEMENT                | 1
    JACOB        | BUSINESS_MANAGEMENT                | 1
    MICHAEL      | BUSINESS_MANAGEMENT                | 1
    JOHN         | BUSINESS_MANAGEMENT                | 1
    WYATT        | BUSINESS_MANAGEMENT                | 1
    CARTER       | BUSINESS_MANAGEMENT                | 1
    JULIAN       | BUSINESS_MANAGEMENT                | 1
    LUKE         | BUSINESS_MANAGEMENT                | 1
    GRAYSON      | BUSINESS_MANAGEMENT                | 1
    LIAM         | INTRODUCTION_TO_BUSINESS           | 1
    LUKE         | INTRODUCTION_TO_BUSINESS           | 1
    LIAM         | PERSONAL_FINANCE                   | 1
    NOAH         | PERSONAL_FINANCE                   | 1
    ELIJAH       | PERSONAL_FINANCE                   | 1
    LOGAN        | PERSONAL_FINANCE                   | 1
    LIAM         | APP_DEVELOPMENT                    | 1
    ANTHONY      | APP_DEVELOPMENT                    | 1
    NOAH         | APP_DEVELOPMENT                    | 1
    WILLIAM      | APP_DEVELOPMENT                    | 1
    ELIJAH       | APP_DEVELOPMENT                    | 1
    ETHAN        | APP_DEVELOPMENT                    | 1
    LOGAN        | APP_DEVELOPMENT                    | 1
    DYLAN        | APP_DEVELOPMENT                    | 1
    LIAM         | AUDIO_PRODUCTION                   | 1
    ANTHONY      | AUDIO_PRODUCTION                   | 1
    NOAH         | AUDIO_PRODUCTION                   | 1
    OLIVER       | AUDIO_PRODUCTION                   | 1
    WILLIAM      | AUDIO_PRODUCTION                   | 1
    ELIJAH       | AUDIO_PRODUCTION                   | 1
    JAMES        | AUDIO_PRODUCTION                   | 1
    LEVI         | AUDIO_PRODUCTION                   | 1
    BENJAMIN     | AUDIO_PRODUCTION                   | 1
    LUCAS        | AUDIO_PRODUCTION                   | 1
    MATEO        | AUDIO_PRODUCTION                   | 1
    DAVID        | AUDIO_PRODUCTION                   | 1
    LOGAN        | AUDIO_PRODUCTION                   | 1
    ISAAC        | AUDIO_PRODUCTION                   | 1
    LEO          | AUDIO_PRODUCTION                   | 1
    MASON        | AUDIO_PRODUCTION                   | 1
    LINCOLN      | AUDIO_PRODUCTION                   | 1
    JAYDEN       | AUDIO_PRODUCTION                   | 1
    JAXON        | AUDIO_PRODUCTION                   | 1
    LIAM         | COMPUTER_PROGRAMMING               | 1
    OLIVER       | COMPUTER_PROGRAMMING               | 1
    ASHER        | COMPUTER_PROGRAMMING               | 1
    ELIJAH       | COMPUTER_PROGRAMMING               | 1
    CHRISTOPHER  | COMPUTER_PROGRAMMING               | 1
    LUCAS        | COMPUTER_PROGRAMMING               | 1
    DAVID        | COMPUTER_PROGRAMMING               | 1
    JOSIAH       | COMPUTER_PROGRAMMING               | 1
    DYLAN        | COMPUTER_PROGRAMMING               | 1
    ANDREW       | COMPUTER_PROGRAMMING               | 1
    THOMAS       | COMPUTER_PROGRAMMING               | 1
    WILLIAM      | COMPUTER_REPAIR                    | 1
    LIAM         | FILM_PRODUCTION                    | 1
    JOSHUA       | FILM_PRODUCTION                    | 1
    NOAH         | FILM_PRODUCTION                    | 1
    OLIVER       | FILM_PRODUCTION                    | 1
    ASHER        | FILM_PRODUCTION                    | 1
    ELIJAH       | FILM_PRODUCTION                    | 1
    EZRA         | FILM_PRODUCTION                    | 1
    BENJAMIN     | FILM_PRODUCTION                    | 1
    LUCAS        | FILM_PRODUCTION                    | 1
    MATEO        | FILM_PRODUCTION                    | 1
    DAVID        | FILM_PRODUCTION                    | 1
    HUDSON       | FILM_PRODUCTION                    | 1
    JOSIAH       | FILM_PRODUCTION                    | 1
    DYLAN        | FILM_PRODUCTION                    | 1
    THOMAS       | FILM_PRODUCTION                    | 1
    LIAM         | GRAPHIC_DESIGN                     | 1
    LIAM         | MEDIA_TECHNOLOGY                   | 1
    NOAH         | MEDIA_TECHNOLOGY                   | 1
    DYLAN        | MEDIA_TECHNOLOGY                   | 1
    SEBASTIAN    | MUSIC_PRODUCTION                   | 1
    CHARLES      | MUSIC_PRODUCTION                   | 1
    JOSEPH       | MUSIC_PRODUCTION                   | 1
    LIAM         | TYPING                             | 1
    NOAH         | TYPING                             | 1
    ELIJAH       | TYPING                             | 1
    DYLAN        | TYPING                             | 1
    LIAM         | VIDEO_GAME_DEVELOPMENT             | 1
    NOAH         | VIDEO_GAME_DEVELOPMENT             | 1
    LIAM         | WEB_DESIGN                         | 1
    CALEB        | WEB_DESIGN                         | 1
    ISAIAH       | WEB_DESIGN                         | 1
    WILLIAM      | WEB_DESIGN                         | 1
    ELIJAH       | WEB_DESIGN                         | 1
    ETHAN        | WEB_DESIGN                         | 1
    JACOB        | WEB_DESIGN                         | 1
    LOGAN        | WEB_DESIGN                         | 1
    LIAM         | WORD_PROCESSING                    | 1
    ELIJAH       | AMERICAN_LITERATURE                | 1
    LIAM         | BRITISH_LITERATURE                 | 1
    WILLIAM      | BRITISH_LITERATURE                 | 1
    ELIJAH       | BRITISH_LITERATURE                 | 1
    ETHAN        | BRITISH_LITERATURE                 | 1
    JACOB        | BRITISH_LITERATURE                 | 1
    JACK         | BRITISH_LITERATURE                 | 1
    SAMUEL       | BRITISH_LITERATURE                 | 1
    LIAM         | CONTEMPORARY_LITERATURE            | 1
    ELIJAH       | CONTEMPORARY_LITERATURE            | 1
    LEVI         | CONTEMPORARY_LITERATURE            | 1
    ISAAC        | CONTEMPORARY_LITERATURE            | 1
    LINCOLN      | CONTEMPORARY_LITERATURE            | 1
    JAXON        | CONTEMPORARY_LITERATURE            | 1
    LIAM         | COMMUNICATION_SKILLS               | 1
    NOAH         | COMMUNICATION_SKILLS               | 1
    OLIVER       | COMMUNICATION_SKILLS               | 1
    ELIJAH       | COMMUNICATION_SKILLS               | 1
    BENJAMIN     | COMMUNICATION_SKILLS               | 1
    LUCAS        | COMMUNICATION_SKILLS               | 1
    DAVID        | COMMUNICATION_SKILLS               | 1
    JOHN         | COMMUNICATION_SKILLS               | 1
    LUKE         | COMMUNICATION_SKILLS               | 1
    ANDREW       | COMMUNICATION_SKILLS               | 1
    MAVERICK     | COMMUNICATION_SKILLS               | 1
    LIAM         | DEBATE                             | 1
    NOAH         | DEBATE                             | 1
    LIAM         | ENGLISH_LANGUAGE_AND_COMPOSITION   | 1
    ELIJAH       | ENGLISH_LANGUAGE_AND_COMPOSITION   | 1
    BENJAMIN     | ENGLISH_LANGUAGE_AND_COMPOSITION   | 1
    MASON        | ENGLISH_LANGUAGE_AND_COMPOSITION   | 1
    MATEO        | HUMANITIES                         | 1
    DAVID        | HUMANITIES                         | 1
    ISAAC        | HUMANITIES                         | 1
    LINCOLN      | HUMANITIES                         | 1
    LIAM         | JOURNALISM                         | 1
    COLTON       | JOURNALISM                         | 1
    ELIAS        | JOURNALISM                         | 1
    ELIJAH       | JOURNALISM                         | 1
    LEVI         | JOURNALISM                         | 1
    LIAM         | LITERARY_ANALYSIS                  | 1
    AARON        | LITERARY_ANALYSIS                  | 1
    ELIAS        | LITERARY_ANALYSIS                  | 1
    ELIJAH       | LITERARY_ANALYSIS                  | 1
    LEVI         | LITERARY_ANALYSIS                  | 1
    AARON        | MODERN_LITERATURE                  | 1
    ELIAS        | MODERN_LITERATURE                  | 1
    LEVI         | MODERN_LITERATURE                  | 1
    AARON        | POETRY                             | 1
    ELIAS        | POETRY                             | 1
    LEVI         | POETRY                             | 1
    ELIAS        | POPULAR_LITERATURE                 | 1
    LEVI         | POPULAR_LITERATURE                 | 1
    BENJAMIN     | RHETORIC                           | 1
    ISAAC        | RHETORIC                           | 1
    MASON        | RHETORIC                           | 1
    ELIJAH       | TECHNICAL_WRITING                  | 1
    ANTHONY      | WORKS_OF_SHAKESPEARE               | 1
    ELIJAH       | WORKS_OF_SHAKESPEARE               | 1
    LEVI         | WORKS_OF_SHAKESPEARE               | 1
    LIAM         | WORLD_LITERATURE                   | 1
    ETHAN        | WORLD_LITERATURE                   | 1
    ALEXANDER    | WORLD_LITERATURE                   | 1
    HENRY        | WORLD_LITERATURE                   | 1
    JACOB        | WORLD_LITERATURE                   | 1
    LOGAN        | WRITTEN_AND_ORAL_COMMUNICATION     | 1
    MASON        | WRITTEN_AND_ORAL_COMMUNICATION     | 1
    ELI          | WRITTEN_AND_ORAL_COMMUNICATION     | 1
    LIAM         | CHEMISTRY_OF_FOODS                 | 1
    ANTHONY      | CHEMISTRY_OF_FOODS                 | 1
    LANDON       | CHEMISTRY_OF_FOODS                 | 1
    JONATHAN     | CHEMISTRY_OF_FOODS                 | 1
    NOLAN        | CHEMISTRY_OF_FOODS                 | 1
    NOAH         | CHEMISTRY_OF_FOODS                 | 1
    HUNTER       | CHEMISTRY_OF_FOODS                 | 1
    OLIVER       | CHEMISTRY_OF_FOODS                 | 1
    WILLIAM      | CHEMISTRY_OF_FOODS                 | 1
    ELIJAH       | CHEMISTRY_OF_FOODS                 | 1
    CAMERON      | CHEMISTRY_OF_FOODS                 | 1
    BENJAMIN     | CHEMISTRY_OF_FOODS                 | 1
    LUCAS        | CHEMISTRY_OF_FOODS                 | 1
    LOGAN        | CHEMISTRY_OF_FOODS                 | 1
    MASON        | CHEMISTRY_OF_FOODS                 | 1
    DYLAN        | CHEMISTRY_OF_FOODS                 | 1
    DYLAN        | CPR_TRAINING                       | 1
    LIAM         | CULINARY_ARTS                      | 1
    ELIJAH       | CULINARY_ARTS                      | 1
    GABRIEL      | CULINARY_ARTS                      | 1
    LIAM         | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    SANTIAGO     | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    JEREMIAH     | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    JOSHUA       | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    NOAH         | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    ASHER        | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    ELIJAH       | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    THEODORE     | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    EZRA         | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    LEVI         | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    RYAN         | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    EZEKIEL      | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    ANGEL        | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    JOSIAH       | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    ROMAN        | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    EASTON       | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    LOGAN        | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    MILES        | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    ROBERT       | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    JAMESON      | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    NICHOLAS     | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    GREYSON      | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    COOPER       | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    IAN          | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    MASON        | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    CARSON       | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    AXEL         | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    JAXSON       | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    DOMINIC      | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    LEONARDO     | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    LUCA         | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    AUSTIN       | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    JORDAN       | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    ADAM         | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    XAVIER       | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    JOSE         | EARLY_CHILDHOOD_DEVELOPMENT        | 1
    LIAM         | EARLY_CHILDHOOD_EDUCATION          | 1
    ANTHONY      | EARLY_CHILDHOOD_EDUCATION          | 1
    NOAH         | EARLY_CHILDHOOD_EDUCATION          | 1
    BENJAMIN     | EARLY_CHILDHOOD_EDUCATION          | 1
    MATEO        | EARLY_CHILDHOOD_EDUCATION          | 1
    LOGAN        | EARLY_CHILDHOOD_EDUCATION          | 1
    ISAAC        | EARLY_CHILDHOOD_EDUCATION          | 1
    MASON        | EARLY_CHILDHOOD_EDUCATION          | 1
    JAXON        | EARLY_CHILDHOOD_EDUCATION          | 1
    LIAM         | FAMILY_STUDIES                     | 1
    ELIJAH       | FAMILY_STUDIES                     | 1
    RYAN         | FAMILY_STUDIES                     | 1
    DYLAN        | FAMILY_STUDIES                     | 1
    DYLAN        | FASHION_AND_RETAIL_MERCHANDISING   | 1
    LIAM         | FASHION_CONSTRUCTION               | 1
    SANTIAGO     | FASHION_CONSTRUCTION               | 1
    JEREMIAH     | FASHION_CONSTRUCTION               | 1
    ASHER        | FASHION_CONSTRUCTION               | 1
    ELIJAH       | FASHION_CONSTRUCTION               | 1
    JOSIAH       | FASHION_CONSTRUCTION               | 1
    ROBERT       | FASHION_CONSTRUCTION               | 1
    JAMESON      | FASHION_CONSTRUCTION               | 1
    GREYSON      | FASHION_CONSTRUCTION               | 1
    DYLAN        | FASHION_CONSTRUCTION               | 1
    LIAM         | HOME_ECONOMICS                     | 1
    NOAH         | HOME_ECONOMICS                     | 1
    JACE         | HOME_ECONOMICS                     | 1
    WILLIAM      | HOME_ECONOMICS                     | 1
    ELIJAH       | HOME_ECONOMICS                     | 1
    CONNOR       | HOME_ECONOMICS                     | 1
    LEVI         | HOME_ECONOMICS                     | 1
    BENJAMIN     | HOME_ECONOMICS                     | 1
    EVERETT      | HOME_ECONOMICS                     | 1
    MATEO        | HOME_ECONOMICS                     | 1
    DECLAN       | HOME_ECONOMICS                     | 1
    LOGAN        | HOME_ECONOMICS                     | 1
    ISAAC        | HOME_ECONOMICS                     | 1
    GRAYSON      | HOME_ECONOMICS                     | 1
    EVAN         | HOME_ECONOMICS                     | 1
    MASON        | HOME_ECONOMICS                     | 1
    JAXON        | HOME_ECONOMICS                     | 1
    LIAM         | INTERIOR_DESIGN                    | 1
    KAYDEN       | INTERIOR_DESIGN                    | 1
    PARKER       | INTERIOR_DESIGN                    | 1
    WESLEY       | INTERIOR_DESIGN                    | 1
    KAI          | INTERIOR_DESIGN                    | 1
    BRAYDEN      | INTERIOR_DESIGN                    | 1
    BRYSON       | INTERIOR_DESIGN                    | 1
    WESTON       | INTERIOR_DESIGN                    | 1
    NOAH         | INTERIOR_DESIGN                    | 1
    ELIJAH       | INTERIOR_DESIGN                    | 1
    BENJAMIN     | INTERIOR_DESIGN                    | 1
    JOHN         | INTERIOR_DESIGN                    | 1
    CARTER       | INTERIOR_DESIGN                    | 1
    LOGAN        | INTERIOR_DESIGN                    | 1
    JULIAN       | INTERIOR_DESIGN                    | 1
    ISAAC        | INTERIOR_DESIGN                    | 1
    MASON        | INTERIOR_DESIGN                    | 1
    JASON        | INTERIOR_DESIGN                    | 1
    ELI          | INTERIOR_DESIGN                    | 1
    EMMETT       | INTERIOR_DESIGN                    | 1
    SAWYER       | INTERIOR_DESIGN                    | 1
    SILAS        | INTERIOR_DESIGN                    | 1
    LOGAN        | NUTRITION                          | 1
    BROOKS       | NUTRITION                          | 1
    MICAH        | NUTRITION                          | 1
    DAMIAN       | NUTRITION                          | 1
    MASON        | NUTRITION                          | 1
    HARRISON     | NUTRITION                          | 1
    ELI          | NUTRITION                          | 1
    WAYLON       | NUTRITION                          | 1
    AIDEN        | NUTRITION                          | 1
    AYDEN        | NUTRITION                          | 1
    VINCENT      | NUTRITION                          | 1
    LIAM         | AMERICAN_SIGN_LANGUAGE             | 1
    NOAH         | AMERICAN_SIGN_LANGUAGE             | 1
    ELIJAH       | AMERICAN_SIGN_LANGUAGE             | 1
    BENJAMIN     | AMERICAN_SIGN_LANGUAGE             | 1
    RYDER        | AMERICAN_SIGN_LANGUAGE             | 1
    WYATT        | AMERICAN_SIGN_LANGUAGE             | 1
    MASON        | AMERICAN_SIGN_LANGUAGE             | 1
    LIAM         | ANCIENT_GREEK                      | 1
    NOAH         | ANCIENT_GREEK                      | 1
    ELIJAH       | ANCIENT_GREEK                      | 1
    ETHAN        | ANCIENT_GREEK                      | 1
    LIAM         | ARABIC                             | 1
    NOAH         | ARABIC                             | 1
    LOGAN        | ARABIC                             | 1
    JACKSON      | ARABIC                             | 1
    OWEN         | ARABIC                             | 1
    KINGSTON     | ARABIC                             | 1
    CHARLES      | ARABIC                             | 1
    JOSEPH       | ARABIC                             | 1
    LIAM         | FRENCH                             | 1
    AIDEN        | FRENCH                             | 1
    MATTHEW      | FRENCH                             | 1
    LIAM         | GERMAN                             | 1
    ELIJAH       | GERMAN                             | 1
    MATEO        | GERMAN                             | 1
    GRAYSON      | GERMAN                             | 1
    JAXON        | GERMAN                             | 1
    ELIJAH       | HEBREW                             | 1
    DYLAN        | HEBREW                             | 1
    JAXON        | HEBREW                             | 1
    LIAM         | JAPANESE                           | 1
    LIAM         | KOREAN                             | 1
    ANTHONY      | KOREAN                             | 1
    NOAH         | KOREAN                             | 1
    OLIVER       | KOREAN                             | 1
    ELIJAH       | KOREAN                             | 1
    THEODORE     | KOREAN                             | 1
    EZRA         | KOREAN                             | 1
    LEVI         | KOREAN                             | 1
    RYAN         | KOREAN                             | 1
    BENJAMIN     | KOREAN                             | 1
    LUCAS        | KOREAN                             | 1
    DAVID        | KOREAN                             | 1
    JOHN         | KOREAN                             | 1
    CARTER       | KOREAN                             | 1
    LOGAN        | KOREAN                             | 1
    JULIAN       | KOREAN                             | 1
    JACKSON      | KOREAN                             | 1
    LUKE         | KOREAN                             | 1
    DAMIAN       | KOREAN                             | 1
    ISAAC        | KOREAN                             | 1
    GRAYSON      | KOREAN                             | 1
    GAVIN        | KOREAN                             | 1
    MASON        | KOREAN                             | 1
    JASON        | KOREAN                             | 1
    HARRISON     | KOREAN                             | 1
    EMMETT       | KOREAN                             | 1
    JORDAN       | KOREAN                             | 1
    JAXON        | KOREAN                             | 1
    JOSEPH       | KOREAN                             | 1
    ADAM         | KOREAN                             | 1
    XAVIER       | KOREAN                             | 1
    ELIJAH       | LATIN                              | 1
    MATEO        | LATIN                              | 1
    JAXON        | LATIN                              | 1
    LIAM         | PORTUGUESE                         | 1
    LANDON       | PORTUGUESE                         | 1
    JONATHAN     | PORTUGUESE                         | 1
    NOAH         | PORTUGUESE                         | 1
    HUNTER       | PORTUGUESE                         | 1
    OLIVER       | PORTUGUESE                         | 1
    JACE         | PORTUGUESE                         | 1
    WILLIAM      | PORTUGUESE                         | 1
    ELIJAH       | PORTUGUESE                         | 1
    CAMERON      | PORTUGUESE                         | 1
    JAMES        | PORTUGUESE                         | 1
    CONNOR       | PORTUGUESE                         | 1
    BENJAMIN     | PORTUGUESE                         | 1
    LUCAS        | PORTUGUESE                         | 1
    EVERETT      | PORTUGUESE                         | 1
    MATEO        | PORTUGUESE                         | 1
    DAVID        | PORTUGUESE                         | 1
    WYATT        | PORTUGUESE                         | 1
    LOGAN        | PORTUGUESE                         | 1
    ISAAC        | PORTUGUESE                         | 1
    GRAYSON      | PORTUGUESE                         | 1
    MASON        | PORTUGUESE                         | 1
    DYLAN        | PORTUGUESE                         | 1
    LINCOLN      | PORTUGUESE                         | 1
    JAXON        | PORTUGUESE                         | 1
    RYAN         | RUSSIAN                            | 1
    RYDER        | RUSSIAN                            | 1
    DYLAN        | RUSSIAN                            | 1
    EMMETT       | SPANISH                            | 1
    NICHOLAS     | ALGEBRA_1                          | 1
    LEONARDO     | ALGEBRA_1                          | 1
    SANTIAGO     | ALGEBRA_2                          | 1
    JEREMIAH     | ALGEBRA_2                          | 1
    TYLER        | ALGEBRA_2                          | 1
    NOAH         | ALGEBRA_2                          | 1
    ASHER        | ALGEBRA_2                          | 1
    THEODORE     | ALGEBRA_2                          | 1
    EZRA         | ALGEBRA_2                          | 1
    LEVI         | ALGEBRA_2                          | 1
    RYAN         | ALGEBRA_2                          | 1
    BENJAMIN     | ALGEBRA_2                          | 1
    EZEKIEL      | ALGEBRA_2                          | 1
    ANGEL        | ALGEBRA_2                          | 1
    JOSIAH       | ALGEBRA_2                          | 1
    ROMAN        | ALGEBRA_2                          | 1
    EASTON       | ALGEBRA_2                          | 1
    LOGAN        | ALGEBRA_2                          | 1
    MILES        | ALGEBRA_2                          | 1
    ROBERT       | ALGEBRA_2                          | 1
    JAMESON      | ALGEBRA_2                          | 1
    NICHOLAS     | ALGEBRA_2                          | 1
    GREYSON      | ALGEBRA_2                          | 1
    ISAAC        | ALGEBRA_2                          | 1
    COOPER       | ALGEBRA_2                          | 1
    GRAYSON      | ALGEBRA_2                          | 1
    IAN          | ALGEBRA_2                          | 1
    MASON        | ALGEBRA_2                          | 1
    CARSON       | ALGEBRA_2                          | 1
    AXEL         | ALGEBRA_2                          | 1
    JAXSON       | ALGEBRA_2                          | 1
    DOMINIC      | ALGEBRA_2                          | 1
    ISAAC        | CONSUMER_EDUCATION                 | 1
    JAYDEN       | ENTREPRENEURIAL_SKILLS             | 1
    THEODORE     | MARKETING                          | 1
    GABRIEL      | ANIMATION                          | 1
    RYAN         | WEB_PROGRAMMING                    | 1
    GABRIEL      | ENGLISH_LITERATURE_AND_COMPOSITION | 1
    CONNOR       | CPR_TRAINING                       | 1
    BENNETT      | NUTRITION                          | 1
    TYLER        | ALGEBRA_1                          | 1
    NATHAN       | CREATIVE_WRITING                   | 2
    ADRIAN       | CREATIVE_WRITING                   | 2
    CHRISTIAN    | CREATIVE_WRITING                   | 2
    ROWAN        | CHINESE                            | 3
    GEORGE       | CHINESE                            | 3
    LUIS         | CHINESE                            | 3
    CHASE        | CHINESE                            | 3
    COLE         | CHINESE                            | 3
    NATHANIEL    | CHINESE                            | 3
    ZACHARY      | CHINESE                            | 3
    ASHTON       | CHINESE                            | 3
    BRAXTON      | ITALIAN                            | 4
    

    db小提琴here

    【讨论】:

      【解决方案3】:

      您可以使用分层查询来查找组:

      SELECT MIN( id ) AS id,
             student_name,
             subject_name
      FROM   (
        SELECT CONNECT_BY_ROOT( id ) AS id,
               student_name,
               subject_name
        FROM   (
          SELECT student_name,
                 subject_name,
                 ROW_NUMBER() OVER ( ORDER BY subject_name, student_name ) AS id,
                 ROW_NUMBER() OVER ( PARTITION BY subject_name ORDER BY student_name ) AS rn
          FROM   student_subject s
        )
        START WITH rn = 1
        CONNECT BY NOCYCLE
               PRIOR student_name = student_name
        OR     PRIOR subject_name = subject_name
      )
      GROUP BY
             student_name,
             subject_name
      ORDER BY
             id,
             subject_name,
             student_name
      

      其中,对于样本数据:

      CREATE TABLE student_subject ( student_name, subject_name ) AS
      SELECT 'SMITH', 'CHEMISTRY' FROM DUAL UNION ALL
      SELECT 'ROBIN', 'PHYSICS' FROM DUAL UNION ALL
      SELECT 'SAM', 'PHYSICS' FROM DUAL UNION ALL
      SELECT 'SAM', 'MATH' FROM DUAL UNION ALL
      SELECT 'JENNY', 'MATH' FROM DUAL UNION ALL
      SELECT 'JENNY', 'ACCOUNTS' FROM DUAL UNION ALL
      SELECT 'DON', 'ENGLISH' FROM DUAL UNION ALL
      SELECT 'DON', 'SPANISH' FROM DUAL UNION ALL
      SELECT 'RON', 'HISTORY' FROM DUAL UNION ALL
      SELECT 'JOVAN', 'HISTORY' FROM DUAL;
      

      输出:

      身份证 |学生名 | SUBJECT_NAME -: | :----------- | :----------- 1 |珍妮 |账户 1 |珍妮 |数学 1 |山姆 |数学 1 |罗宾 |物理 1 |山姆 |物理 2 |史密斯 |化学 3 |唐 |英语 3 |唐 |西班牙语 4 |约万 |历史 4 |罗恩 |历史

      db小提琴here

      【讨论】:

      • 我同意——我喜欢 CONNECT BY 的这种东西。但我认为 OP 的实际数据集连接性太高,无法在这种情况下表现良好。例如,即使忽略个别学生,只看班级之间的关系,也有上千种方法可以从会计到打字。
      • @MatthewMcPeak 我知道,它适用于小样本,这就是 OP 在他们(现已删除)这个问题的原始版本上发布的内容。这就是为什么我使用 PL/SQL 流水线函数发布第二个答案的原因,该函数确实适用于大型样本。
      【解决方案4】:

      虽然您没有指定分类标准,但在分析您的输出表后,我们可能会假设:

      • Group1:一对一(学生-受试者对);
      • Group2:多对多;
      • Group3:一对多;
      • Group4:多对一;

      实施此分类的一种方法是按组创建某种汇总统计信息,例如最大计数。所以:

      1. 首先,您可以按学科统计学生人数(创建student_by_subject 变量)。
      2. 其次,您按学生 (subject_by_student) 计算科目,并按学生 (max_student) 计算 student_by_subject 的最大值。
      3. 第三,按主题计算subject_by_student 的最大值(max_subject);
      4. 第四,根据最大计数变量对组进行分类;

      这可以在单个查询中完成:

      create table want as 
      select
      student_name, subject_name,
      case when max_student=1 and max_subject=1 then 1
           when max_student>1 and max_subject>1 then 2
           when max_student=1 and max_subject>1 then 3
           when max_student>1 and max_subject=1 then 4 end as NEW_GROUP
      from (select subject_name, student_name, max_student, 
          max(subject_by_student) as max_subject 
          from (select student_name, subject_name, student_by_subject, 
              count(subject_name) as subject_by_student, 
              max(student_by_subject) as max_student
              from (select student_name, subject_name, 
                  count(student_name) as student_by_subject
                  from student_subject group by subject_name)
              group by student_name)
          group by subject_name)
      ORDER by NEW_GROUP;
      

      【讨论】:

      • 这会因许多语法错误而失败。 GROUP 是一个关键字,如果不引用它就不能使用它。您需要在 * 通配符前加上表名/别名。然后你会得到ORA-00979: not a GROUP BY expression
      • 嗯,好的。感谢您指出这些错误。我在我的机器上运行它,一切正常。我将根据您的 cmets 更正我的答案
      • db<>fiddle 这是我调试的开始......我在第 3 个错误上停止了,因为如何纠正您的解决方案并不明显(而且我不确定它是否真的有效在我包含的样本数据中,有两个大小完全相同的组)。
      • 好吧,我修改了代码以避免你提到的错误。我设法根据问题顶部提供的“示例源表”获得所需的输出。这是因为“目标输出”是基于它的。我没有在“实际数据”上运行,因为没有基于它的期望输出。
      • 您是否在 Oracle 中运行它,因为它仍然提供 ORA-00979: not a GROUP BY expression db<>fiddle
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-19
      • 1970-01-01
      • 2017-12-24
      • 2021-06-17
      • 2021-10-03
      • 2018-11-02
      • 2015-10-26
      相关资源
      最近更新 更多