Форум программистов, компьютерный форум, киберфорум
Microsoft SQL Server
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 19.10.2022
Сообщений: 9

MS SQL Создать функцию, формирующую направления для студентов, не сдавших экзамены, к случайным преподавателям

18.01.2024, 19:59. Показов 1240. Ответов 7

Студворк — интернет-сервис помощи студентам
Всех приветствую, стоит передо мной вот такая задачка: "Создать функцию, формирующую направления для студентов, не сдавших экзамены, к случайным преподавателям, ведущим эти дисциплины", имеются следующие таблицы:

Группы (Номер_Группы, Староста_Группы)

Студенты (Код_Студента, Фамилия, Имя, Отчество, Номер_Зачетной_Книжки, Номер_Группы, Домашний_Адрес, Телефон)

Дисциплины (Код_Дисциплины, Название, Количество_Часов, Описание)

Результаты_Сессии (Код_Студента, Код_Дисциплины, Дата, Вид_Контроля, Оценка)

Преподаватели (Код_Преподавателя, Фамилия, Имя, Отчество, Должность, Ученая_Степень, Дата_Приема_На_Работу, Номер_Кафедры)

Нагрузка (Код_Дисциплины, Код_Преподавателя)

Скриншот диаграммы:


Условия решение задачи: Нельзя использовать оконные функции, нельзя использовать CTE, задачка должна решаться элементарно, без слишком усложненных конструкций. Для рандома используется представление:
SQL
1
2
3
CREATE VIEW dbo.Рандом AS 
 SELECT NEWID() AS Рандомное_Значение; 
GO
(Поскольку при создании функции нельзя использовать ORDER BY NEWID(), это что-то типо обхода)

Решения которые были забракованы:
1.
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SELECT
s.Код_Студента,
s.Фамилия,
s.Имя,
s.Отчество,
s.Номер_Группы,
r.Код_Дисциплины,
p.Код_Преподавателя,
p.Фамилия AS Преподаватель_Фамилия,
p.Имя AS Преподаватель_Имя
FROM
Студенты s
JOIN Результаты_Сессии r ON s.Код_Студента = r.Код_Студента
JOIN Нагрузка n ON r.Код_Дисциплины = n.Код_Дисциплины
JOIN Преподаватели p ON n.Код_Преподавателя = p.Код_Преподавателя
CROSS JOIN Рандом AS rnd
WHERE
r.Вид_Контроля = 'Экзамен'
AND r.Оценка < 3
ORDER BY ROW_NUMBER() OVER (PARTITION BY s.Код_Студента ORDER BY rnd.Рандомное_значение)
Причина браковки: Используется оконная функция

2.
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT  T1.*, 
    (
       SELECT Код_Преподавателя FROM
       (
        SELECT TOP 1 T2.Код_Преподавателя, (SELECT Рандомное_Значение FROM Рандом) AS rnd
        FROM Нагрузка AS T2
        JOIN Результаты_Сессии AS T3 ON T2.Код_Дисциплины = T3.Код_Дисциплины
        WHERE T3.Код_Студента = T1.Код_Студента AND T2.Код_Дисциплины = T1.Код_Дисциплины
        ORDER BY rnd
        ) AS Случайный_преподователь
    ) AS Код_Преподавателя
FROM 
   Результаты_Сессии AS T1
WHERE T1.Вид_Контроля = 'Экзамен' AND T1.Оценка <= 2;
Причина браковки: По словам преподавателя данное решение является нелогичным, а именно T3.Код_Студента = T1.Код_Студента это условие делает запрос нелогичным. Но без него рандом начинает работать криво и преподаватели рандомятся по дисциплинам. Пример:

Если не убирать условие T3.Код_Студента = T1.Код_Студента, то рандом начинает работать правильно. Пример:

Прошу вас помочь с решением и объяснением
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
18.01.2024, 19:59
Ответы с готовыми решениями:

Массив студентов первого курса. Вывести процент студентов, сдавших все экзамены на 4, 5
Добрый вечер. Задание следующее: В массиве содержится информация о сдаче зимней сессии студентами первого курса. Сведения о каждом...

Определить процент студентов, сдавших экзамены на 4 и 5
Информация об итогах сдачи сессии каждым студентом представлена в следующем порядке: Фамилия И.О., номер группы, экзаменационные оценки по...

Вывести студентов, сдавших все экзамены
Написать запрос в котором выводятся студенты сдавшие все экзамены, не зависимо от оценок. Каждый студент может сдать разное число...

7
 Аватар для Аватар
5393 / 1465 / 513
Регистрация: 31.05.2012
Сообщений: 5,153
18.01.2024, 21:00
если не начудил на коленке то примерно так
T-SQL
1
2
3
4
5
6
7
8
select s.Код_Студента,r.Код_Дисциплины,
  (select top 1 n.Код_Преподавателя
     from Нагрузка n CROSS JOIN Рандом AS rnd
     where n.Код_Дисциплины=r.Код_Дисциплины
     order by rnd.Рандомное_Значение) Код_Преподавателя
FROM
  Студенты s
    JOIN Результаты_Сессии r ON s.Код_Студента = r.Код_Студента and r.Вид_Контроля = 'Экзамен' AND r.Оценка < 3
0
0 / 0 / 0
Регистрация: 19.10.2022
Сообщений: 9
18.01.2024, 21:25  [ТС]
В вашем решении тоже получается, что рандомится преподаватель только по дисциплинам, а надо чтобы у каждого студента радомился преподаватель.
0
 Аватар для Аватар
5393 / 1465 / 513
Регистрация: 31.05.2012
Сообщений: 5,153
18.01.2024, 21:56
тогда брось сюда скрипты создания и заполнения таблиц, а то достаточно сложно на коленке без отладки получить приемлимый результат ). а рандом через вьюху обязательно? Без нее проще было бы )
0
0 / 0 / 0
Регистрация: 19.10.2022
Сообщений: 9
18.01.2024, 22:51  [ТС]
Насколько я знаю, и насколько я тестил. При создании функции всякие функции рандома по типу rand или newid не работают (ругается сам sql), поэтому единственный обход этого, через представление.

Код таблиц:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
 CREATE TABLE Группы (
            Номер_Группы NVARCHAR(10) CONSTRAINT PK_Группы PRIMARY KEY,
            Староста_Группы INT CONSTRAINT NN_СтаростаГруппы NULL
        );
 
        CREATE TABLE Студенты (
            Код_Студента INT CONSTRAINT PK_Студенты PRIMARY KEY,
            Фамилия NVARCHAR(255) CONSTRAINT NN_Фамилия NOT NULL,
            Имя NVARCHAR(255) CONSTRAINT NN_Имя NOT NULL,
            Отчество NVARCHAR(255) CONSTRAINT N_Отчество NULL,
            Номер_Зачетной_Книжки NVARCHAR(20) CONSTRAINT NN_НомерЗачетнойКнижки NOT NULL,
            Номер_Группы NVARCHAR(10) CONSTRAINT NN_НомерГруппы NOT NULL,
            Домашний_Адрес NVARCHAR(255) CONSTRAINT N_ДомашнийАдресс NULL,
            Телефон NVARCHAR(20) CONSTRAINT N_Телефон NULL
            CONSTRAINT FK_Студенты_Группы FOREIGN KEY (Номер_группы) REFERENCES Группы (Номер_группы),
        );
 
        ALTER TABLE Группы
        ADD CONSTRAINT FK_Группы_Студенты1
        FOREIGN KEY (Староста_Группы)
        REFERENCES Студенты (Код_Студента);
 
        CREATE TABLE Дисциплины (
            Код_Дисциплины INT CONSTRAINT PK_Дисциплины PRIMARY KEY,
            Название NVARCHAR(255) CONSTRAINT NN_Название NOT NULL,
            Количество_Часов INT CONSTRAINT NN_КоличествоЧасов NOT NULL,
            Описание NVARCHAR(MAX) CONSTRAINT N_Описание NULL
        );
 
        CREATE TABLE Результаты_Сессии (
            Код_Студента INT CONSTRAINT NN_КодСтудента NOT NULL,
            Код_Дисциплины INT CONSTRAINT NN_КодДисциплины NOT NULL,
            Дата DATE CONSTRAINT NN_Дата NOT NULL,
            Вид_Контроля NVARCHAR(50) CONSTRAINT NN_ВидКонтроля NOT NULL,
            Оценка INT CONSTRAINT NN_Оценка NOT NULL,
            CONSTRAINT PK_РезультатыСессии PRIMARY KEY (Код_Студента, Код_Дисциплины),
            CONSTRAINT FK_РезультатыСессии_Студенты FOREIGN KEY (Код_Студента) REFERENCES Студенты (Код_Студента),
            CONSTRAINT FK_РезультатыСессии_Дисциплины FOREIGN KEY (Код_Дисциплины) REFERENCES Дисциплины (Код_Дисциплины)
        );
 
        CREATE TABLE Преподаватели (
            Код_Преподавателя INT CONSTRAINT PK_Преподаватели PRIMARY KEY,
            Фамилия NVARCHAR(255) CONSTRAINT NN_Фамилия NOT NULL,
            Имя NVARCHAR(255) CONSTRAINT NN_Имя NOT NULL,
            Отчество NVARCHAR(255) CONSTRAINT N_Отчество NULL,
            Должность NVARCHAR(50) CONSTRAINT NN_Должность NOT NULL,
            Ученая_Степень NVARCHAR(50) CONSTRAINT NN_УченаяСтепень NOT NULL,
            Дата_Приема_На_Работу DATE CONSTRAINT NN_ДатаПриемаНаРаботу NOT NULL,
            Номер_Кафедры NVARCHAR(20) CONSTRAINT NN_НомерКафедры NOT NULL,
        );
 
        CREATE TABLE Нагрузка (
            Код_Дисциплины INT CONSTRAINT NN_КодДисциплины NOT NULL,
            Код_Преподавателя INT CONSTRAINT NN_КодПреподавателя NOT NULL,
            CONSTRAINT PK_Нагрузка PRIMARY KEY (Код_Дисциплины, Код_Преподавателя),
            CONSTRAINT FK_Нагрузка_Дисциплины FOREIGN KEY (Код_Дисциплины) REFERENCES Дисциплины (Код_Дисциплины),
            CONSTRAINT FK_Нагрузка_Преподаватели FOREIGN KEY (Код_Преподавателя) REFERENCES Преподаватели (Код_Преподавателя)
        );
 
--Заполнение таблиц
INSERT INTO Группы (Номер_Группы, Староста_Группы)
VALUES
    ('21ПКС3-5Д', NULL),
    ('21ИС2-5Д', NULL)
 
INSERT INTO Студенты (Код_Студента, Фамилия, Имя, Отчество, Номер_Зачетной_Книжки, Номер_Группы, Домашний_Адрес, Телефон)
VALUES
    (1, 'Иванов', 'Иван', 'Иванович', '12345', '21ПКС3-5Д', 'Адрес2', 'Телефон1'),
    (2, 'Петров', 'Петр', 'Петрович', '54321', '21ПКС3-5Д', 'Адрес2', 'Телефон2'),
    (3, 'Денис', 'Петр', 'Петрович', '543221', '21ИС2-5Д', 'Адрес2', 'Телефон2'),
    (4, 'Игорь', '123', '123', '543231', '21ИС2-5Д', 'Адрес2', 'Телефон2')
 
INSERT INTO Дисциплины (Код_Дисциплины, Название, Количество_Часов, Описание)
VALUES
    (1, 'Математика', 60, 'Описание математики'),
    (2, 'Физика', 45, 'Описание физики'),
    (3, 'Программирование в компьютерных системах', 45, 'Описание программирования')
 
INSERT INTO Результаты_Сессии (Код_Студента, Код_Дисциплины, Дата, Вид_Контроля, Оценка)
VALUES
    (1, 1, '2023-06-15', 'Зачет', 2),
    (2, 2, '2023-06-15', 'Зачет', 2),
    (3, 2, '2023-06-15', 'Зачет', 5),
    (4, 1, '2023-06-15', 'Зачет', 5),
    (1, 3, '2023-06-15', 'Экзамен', 2),
    (2, 3, '2023-06-15', 'Экзамен', 2),
    (3, 3, '2023-06-15', 'Экзамен', 2),
    (4, 3, '2023-06-15', 'Экзамен', 2),
    (4, 2, '2023-06-15', 'Экзамен', 2)
 
INSERT INTO Преподаватели (Код_Преподавателя, Фамилия, Имя, Отчество, Должность, Ученая_Степень, Дата_Приема_На_Работу, Номер_Кафедры)
VALUES
    (1, 'Сидоров', 'Иван', 'Петрович', 'Преподаватель', 'Кандидат наук', '2020-01-15', 'Кафедра1'),
    (2, 'Петров', 'Петр', 'Иванович', 'Доцент', 'Доктор наук', '2019-08-20', 'Кафедра2'),
    (3, 'Антон', 'Иван', 'Олегович', 'Доцент', 'Доктор наук', '2019-08-20', 'Кафедра3')
 
INSERT INTO Нагрузка (Код_Дисциплины, Код_Преподавателя)
VALUES
    (1, 1),
    (2, 2),
    (3, 1),
    (3, 2),
    (3, 3),
    (2, 3)
0
 Аватар для Аватар
5393 / 1465 / 513
Регистрация: 31.05.2012
Сообщений: 5,153
19.01.2024, 10:46
Лучший ответ Сообщение было отмечено L1nix как решение

Решение

SQL
1
2
3
4
5
6
7
8
SELECT u.Код_Студента,u.Код_Дисциплины,CAST(SUBSTRING(MIN(u.rnd),37,2) AS INT)
  FROM 
    (SELECT s.Код_Студента,r.Код_Дисциплины,
        CAST((SELECT Рандомное_Значение FROM Рандом) AS VARCHAR(36))+CAST(n.Код_Преподавателя AS VARCHAR(2)) rnd
      FROM Студенты s
        JOIN Результаты_Сессии r ON s.Код_Студента = r.Код_Студента AND r.Вид_Контроля = 'Экзамен' AND r.Оценка < 3
        JOIN Нагрузка n ON n.Код_Дисциплины=r.Код_Дисциплины) u
  GROUP BY u.Код_Студента,u.Код_Дисциплины
1
0 / 0 / 0
Регистрация: 19.10.2022
Сообщений: 9
19.01.2024, 11:53  [ТС]
Решение рабочее, но я не совсем понимаю зачем тут нужны преобразования, минимальные значения. Можете объяснить?
0
 Аватар для Аватар
5393 / 1465 / 513
Регистрация: 31.05.2012
Сообщений: 5,153
19.01.2024, 12:34
не обязательно же сортировка или ровнумбер по рандому. можно выбрать и минимум вместо сортировки, ну а доступ к коду - изврат засунув его в этот минимум. понятно что вся идея получить рандом по каждому студенту и дисциплине
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.01.2024, 12:34
Помогаю со студенческими работами здесь

Структуры: определить процент студентов, сдавших экзамены на 4 и 5
Информация об итогах сдачи сессии каждым студентом представлена в следующем порядке: Фамилия И.О., номер группы, экзаменационные оценки по...

Составить ведомость студентов, сдавших экзамены за семестр
Составить ведомость студентов, сдавших экзамены за семестр. Для работы с данными использовать структуру типа ' запись ' . Поля должны...

Сделать функцию: определение процента студентов, сдавших все экзамены на "4", "5"
содержащую информацию об итогах сессии на 1-м курсе: фамилия (12 букв). группа (целое число от 1 до 16), четыре оценки (&quot;2&quot;,...

Подсчитать количество студентов в каждой группе, сдавших экзамены на 4 и 5
Структура элемента массива карточка студента: фамилия, имя, отчество, курс, группа, первый семестр (математика, физика, история), второй...

Определить количество студентов, сдавших экзамены без троек
Известны результаты сдачи двух экзаменов десятью студентами. Определить количество студентов, сдавших экзамены без троек. Очень нужно....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru