SQL: повторяющиеся экземпляры в одну строку

Я запускаю базовый SQL-запрос в нашей базе данных, который возвращает данные об учениках. Студент может иметь несколько экземпляров на разных курсах, например:

StudentID        StudentFullName        Course        StartDate
123456           J.Bloggs               BA            01/11/2012
123456           J.Bloggs               MBA           01/07/2015
234567           R.Head                 BA            09/04/2014

То, что я пытаюсь сделать, - это объединить дубликат записи ученика (возможно, на основе идентификатора или имени) и поместить данные курса в одну строку, в результате чего конечный результат в идеале будет выглядеть следующим образом:

StudentID        StudentFullName        Course1       StartDate1       Course2    StartDate2
123456           J.Bloggs               BA            01/11/2012       MBA        01/07/2015
234567           R.Head                 BA            09/04/2014

Могут быть случаи, когда у студентов более двух курсов, поэтому код должен быть гибким, чтобы это разрешить (курс 3, курс 4 и т. Д.).

Я также хотел бы выполнить запрос, чтобы найти студентов, начавших курс "Курс1" через определенный промежуток времени (>= "2014/08/01").

До сих пор мне удавалось воссоздать желаемый результат вручную, запустив исходный код и затем отредактировав его в электронной таблице (это отнимает много времени).

3 ответа

Тем более, что количество ваших курсов является гибким, вы не сможете поместить это в одну таблицу. Таким образом, SQL Server не поддерживает "гибкие таблицы столбцов" как концепцию.

Вместо этого ваша проблема может быть одной из нормализации к форме 2NF.

Рассмотрите возможность создания новой таблицы StudentCourses со столбцами Student ID, Course, Start Date. У такого студента, как J.Bloggs, будет две записи, а у R.Head - только одна. Ваша текущая таблица учеников остается только с информацией ученика, такой как имя, дата рождения, кредиты и т. Д.

Затем, в зависимости от ваших потребностей, вы всегда можете создавать запросы или представления, которые собирают эту информацию.

Используете ли вы SQL в любом другом языке программирования? Если это так, вы можете использовать if-Statement для добавления новых столбцов, но динамическое добавление или удаление столбцов может вызвать аномалии. Я думаю, что создание отдельной таблицы даст вам лучшие результаты. Тогда у вас должно быть три таблицы:

Данныестудента (StudentID, StudentFullName)

Курсы(CourseID, CourseName)

Студенческие курсы(CourseID,StudentID, StartDate)

Это оптимизированная схема.

Надеюсь, я мог бы помочь, если нет, пожалуйста, не стесняйтесь задавать дополнительные вопросы.

РЕДАКТИРОВАТЬ: Возможно, потребуется больше усилий, потому что курсы хранятся отдельно, но это должно быть самым быстрым и наиболее экономичным решением для хранения. как уже упоминалось в комментарии: это нормализация схемы.

Возможно, проще было бы схема с двумя таблицами: StudentData(StudentID, StudentFullName) StudentCourses(CourseName,StudentID, StartDate)

Одним из самых простых способов поворота нескольких столбцов является использование обобщенных выражений регистра.

Вы должны использовать ROW_NUMBER, чтобы определить, является ли курс course1, course2 и т. Д., А затем просто использовать сгенерированный ROW_NUMBER в вашем выражении дела.

SELECT  [StudentID],
        [StudentFullName],
        MAX(CASE WHEN Rn = 1 THEN [Course] END) AS Course1,
        MAX(CASE WHEN Rn = 1 THEN [StartDate] END) AS StartDate1,
        MAX(CASE WHEN Rn = 2 THEN [Course] END) AS Course2,
        MAX(CASE WHEN Rn = 2 THEN [StartDate] END) AS StartDate2
FROM    (
            SELECT  *, ROW_NUMBER() OVER (PARTITION BY [StudentID] ORDER BY [StartDate] DESC) Rn
            FROM    Table1
        ) t
GROUP BY [StudentID],
        [StudentFullName]

Эти запросы также можно выполнять динамически, просто создавая часть MAX(CASE).

Другие вопросы по тегам