Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информатика программирование, учебник.doc
Скачиваний:
1
Добавлен:
01.04.2025
Размер:
22.08 Mб
Скачать

Запрос с группировкой

Запрос этого вида не изменяет информацию в исходных файлах. Этот запрос отбирает из всех записей только те, которые удовлетворяют условиям отбора. Отобранные записи группируются (объединяются) по значениям полей, которые подлежат группировке. Остальные поля записи участвуют как аргументы групповых функций. Наиболее часто используются следующие групповые функции: SUM(<Числовое поле>) - суммирование значений; AVG(<Числовое поле>) - среднее значение поля; COUNT(<Поле>) - количество записей (в некоторых системах программирования - значения полей которых отлично от NIL); MAX(<Числовое поле>) - максимальное значение поля; MIN(<Числовое поле>) - минимальное значение поля.

Пример 14. Разработать запрос к файлу Students.dat, обеспечивающий выборку студентов по группам. Выходом запроса должна быть приведенная ниже таблица.

Группа

Всего студентов

Получают стипендию

Сумма, руб.

1.

ИС-11

2.

ПИ-11

Алгоритм запроса содержит следующие позиции:

  • Открываем файл базы данных Students.dat для чтения.

  • Читаем очередную запись S из файла Students.dat, пока не будет достигнут конец файла.

  • Увеличиваем на 1 счетчик записей N. Копируем два поля из текущей записи S в массив M (M[N].Grup := S.Grup; M[N].Stepa := S.Stepa).

  • Когда достигнут конец файла Students.dat, закрываем файл Students.dat.

  • Состояние массива M отображаем на экране монитора.

  • Если в массиве M нет ни одной записи (N = 0), завершение работы программы.

  • Сортируем массив M по полю M[J].Grup.

  • Состояние массива M отображаем на экране монитора.

  • Подготовка к группировке записей массива M. Полагаем рабочую переменную R_Grup = ' ', которая используется как флаг конца группы при переборе записей массива M. Обнуляем J = 0, счетчик записей в выходной таблице - массиве T.

  • Перебираем по порядку с 1 по N все записи промежуточной таблицы M и для каждой записи M[I] делаем следующие действия. Если новая группа, то есть M[I].Grup ≠ R_Grup, то необходимо: увеличить номер J записи в выходной таблице на 1; запомнить новую группу (R_Grup = M[I].Grup); заполнить поле номер по порядку (T[J].L = J); скопировать код группы (T[J].Grup = M[I].Grup); обнулить счетчики (всего студентов в группе - T[J].KO = 0; количество стипендиатов в группе - T[J].KS = 0; сумма выплат для группы в целом - T[J].SUMMA = 0). Далее для каждой записи группы: увеличить счетчик T[J].KO на 1; если студент I получает стипендию (M[I].Stepa > 0), то увеличить счетчик T[J].KS на 1; добавить к полю T[J].SUMMA величину стипендии M[I].Stepa студента I.

  • Вывести заголовок итоговой таблицы.

  • Вывести значения полей из массива T.

PROGRAM PR131;

Type Student = record {ЗАПИСЬ ОСНОВНОГО ФАЙЛА}

tab : Longint;

Fio : String[15];

Data : String[8];

Grup : String[7];

Stepa: Real;

DEL: BYTE;

DATE: STRING[8]

end;

RAB = record {РАБОЧАЯ ТАБЛИЦА}

Grup : String[7];

Stepa: Real;

end;

OUT = record {ВЫХОДНАЯ ТАБЛИЦА}

L: Integer;

Grup: String[7];

KO: Integer;

KS: Integer;

SUMMA: Real

END;

Var M: ARRAY[1..30] of RAB; R: RAB; I, J, N: INTEGER;

S:Student; St: String; T: ARRAY[1..10] of OUT;

R_Grup : String[7];

StGR: String[7]; S_STEPA: String;

Fs: File of Student;

Begin

Writeln('Введите имя основного файла: ');Readln(St);

Assign (Fs,St); Reset(Fs);

N:=0;

While Not Eof(Fs) {ПРОСМОТР ОСНОВНОГО ФАЙЛА}

Do begin

Read(Fs, S); {ЧТЕНИЕ СООТВ. ЗАПИСИ ИЗ ОСНОВНОГО ФАЙЛА}

N:=N+1;

M[N].Grup := S.Grup; {КОПИРОВАНИЕ ПОЛЕЙ S.Grup, S.Stepa }

M[N].Stepa := S.Stepa; {В РАБОЧИЙ (ПРОМЕЖУТОЧНЫЙ) МАССИВ M}

WRITELN(M[N].Grup:7, M[N].Stepa:10:2)

END; Close(Fs);

READLN; {ПРОСМОТР СОСТОЯНИЯ ПРОМЕЖУТОЧНОЙ ТАБЛИЦЫ M}

IF N = 0

THEN BEGIN WRITELN('Файл ',St,' не имеет ни одной записи'); HALT END;

FOR I:=2 TO N {СОРТИРОВКА МАССИВА ЗАПИСЕЙ M ПО ПОЛЮ Grup}

DO FOR J := N DOWNTO I

DO IF M[J-1].Grup > M[J].Grup

THEN BEGIN

R:=M[J-1]; M[J-1]:=M[J]; M[J]:=R

END;

FOR I:=1 TO N DO WRITELN(M[I].Grup:7, M[I].Stepa:10:2);

READLN; {Просмотр состояния промежуточной таблицы M после сортировки}

R_Grup:= ' '; J:=0;

FOR I:=1 TO N

DO BEGIN

IF M[I].Grup<> R_Grup

THEN BEGIN {НОВАЯ СТРОКА В ВЫХОДНОМ МАССИВЕ}

J := J+1; R_Grup := M[I].Grup;

T[J].L:=J; {НОМЕР ГРУППЫ ПО ПОРЯДКУ}

T[J].Grup:=M[I].Grup; {Код группы}

T[J].KO:=0;

T[J].KS:=0;

T[J].SUMMA:=0

END;

T[J].KO := T[J].KO + 1;

IF M[I].Stepa > 0 THEN T[J].KS := T[J].KS + 1;

T[J].SUMMA := T[J].SUMMA + M[I].Stepa

END;

WRITELN(' N Группа Всего студентов Стипендиатов Сумма, руб.');

FOR I:=1 TO J {Вывод результирующей таблицы на экран}

DO WRITELN(T[I].L:2, T[I].Grup:8, T[I].KO:12, T[I].KS:14, T[I].SUMMA:15:2);

READLN

End.

В результате работы программы на экране монитора будет следующая информация:

N

Группа

Всего студентов

Cтипендиатов

Сумма, руб.

1

ИС-11

13

11

5950.00

2

ПИ-11

10

8

4050.00