View on GitHub

ITMO-PE

My study notes about Program Engineering at University ITMO

MainPage/DataBase/Lab 3

Университет ИТМО

Факультет ФПИ и КТ






Отчёт по лабораторной работе 3

«Информационная система и база данных»

Вариант: 3313110













Студент: Чжоу Хунсян
Группа: P33131
Преподаватель:

1 Текст задания.

Задание.

По варианту, выданному преподавателем, составить и выполнить запросы к базе данных “Учебный процесс”.
根据教师给出的选项,编写并执行对“教育过程(Учебный процесс)”数据库的查询。

Команда для подключения к базе данных ucheb:
连接 ucheb 数据库的命令:

psql -h pg -d ucheb

Отчёт по лабораторной работе должен содержать:
实验室报告必须包含:

Темы для подготовки к защите лабораторной работы:
为实验室工作答辩准备的主题:

Составить запросы на языке SQL (пункты 1-7).

  1. Сделать запрос для получения атрибутов из указанных таблиц, применив фильтры по указанным условиям:
    发出请求从指定表中获取属性,根据指定条件应用过滤器:
    Н_ТИПЫ_ВЕДОМОСТЕЙ, Н_ВЕДОМОСТИ.
    Вывести атрибуты: Н_ТИПЫ_ВЕДОМОСТЕЙ.НАИМЕНОВАНИЕ, Н_ВЕДОМОСТИ.ДАТА.
    显示属性:Н_ТИПЫ_ВЕДОМОСТЕЙ.НАИМЕНОВАНИЕ, Н_ВЕДОМОСТИ.ДАТА
    Фильтры (AND):
    过滤器(与): a) Н_ТИПЫ_ВЕДОМОСТЕЙ.ИД > 3.
    b) Н_ВЕДОМОСТИ.ИД < 1426978.
    Вид соединения: RIGHT JOIN. 连接类型:RIGHT JOIN
  2. Сделать запрос для получения атрибутов из указанных таблиц, применив фильтры по указанным условиям:
    发出请求从指定表中获取属性,并根据指定条件应用过滤器:
    Таблицы: Н_ЛЮДИ, Н_ОБУЧЕНИЯ, Н_УЧЕНИКИ.
    Вывести атрибуты: Н_ЛЮДИ.ФАМИЛИЯ, Н_ОБУЧЕНИЯ.ЧЛВК_ИД, Н_УЧЕНИКИ.ИД.
    显示属性:Н_ЛЮДИ.ФАМИЛИЯ, Н_ОБУЧЕНИЯ.ЧЛВК_ИД, Н_УЧЕНИКИ.ИД
    Фильтры: (AND)
    过滤器(与):
    a) Н_ЛЮДИ.ОТЧЕСТВО > Сергеевич.
    b) Н_ОБУЧЕНИЯ.ЧЛВК_ИД < 112514.
    c) Н_УЧЕНИКИ.ГРУППА > 1101.
    Вид соединения: RIGHT JOIN.
    连接类型:RIGHT JOIN
  3. Вывести число студентов группы 3102, которые младше 20 лет.
    打印 3102 组中 20 岁以下学生的人数
    Ответ должен содержать только одно число.
    答案必须仅包含一个数字。
  4. Найти группы, в которых в 2011 году было ровно 10 обучающихся студентов на ФКТИУ.
    查找 2011 年恰好有 10 名学生在 FKTIU 学习的小组。
    Для реализации использовать подзапрос.
    要实现此目的,请使用子查询。
  5. Выведите таблицу со средним возрастом студентов во всех группах (Группа, Средний возраст), где средний возраст меньше максимального возраста в группе 1100.
    显示所有组中学生的平均年龄(组、平均年龄)的表格,其中平均年龄小于组 1100 中的最大年龄。
  6. Получить список студентов, отчисленных до первого сентября 2012 года с заочной формы обучения (специальность: Программная инженерия). В результат включить:
    获取 2012 年 9 月 1 日之前被函授课程(专业:软件工程)开除的学生名单。 结果包括: номер группы; 组号;
    номер, фамилию, имя и отчество студента; 学生的编号、姓氏、名字和父名;
    номер пункта приказа; 订单商品编号;
    Для реализации использовать соединение таблиц.
    要实现此目的,请使用表连接。
  7. Вывести список студентов, имеющих одинаковые фамилии, но не совпадающие даты рождения.
    显示具有相同姓氏但出生日期不同的学生列表。

2 Реализацию запросов на SQL

-- 1
SELECT "Н_ТИПЫ_ВЕДОМОСТЕЙ"."НАИМЕНОВАНИЕ", "Н_ВЕДОМОСТИ"."ЧЛВК_ИД" FROM "Н_ТИПЫ_ВЕДОМОСТЕЙ"
RIGHT JOIN "Н_ВЕДОМОСТИ" ON "Н_ТИПЫ_ВЕДОМОСТЕЙ"."ИД" = "Н_ВЕДОМОСТИ"."ТВ_ИД"
WHERE
    "Н_ТИПЫ_ВЕДОМОСТЕЙ"."ИД" > 3 AND
    "Н_ВЕДОМОСТИ"."ИД" = 1426978;

-- 2
SELECT "Н_ЛЮДИ"."ФАМИЛИЯ", "Н_ОБУЧЕНИЯ"."ЧЛВК_ИД", "Н_УЧЕНИКИ"."ИД" FROM "Н_ЛЮДИ"
INNER JOIN "Н_ОБУЧЕНИЯ" ON "Н_ЛЮДИ"."ИД" = "Н_ОБУЧЕНИЯ"."ЧЛВК_ИД"
INNER JOIN "Н_УЧЕНИКИ" ON "Н_ОБУЧЕНИЯ"."ЧЛВК_ИД" = "Н_УЧЕНИКИ"."ЧЛВК_ИД"
WHERE
    "Н_ЛЮДИ"."ОТЧЕСТВО" > 'Сергеевич' AND
    "Н_ОБУЧЕНИЯ"."ЧЛВК_ИД" < 112514 AND
    CAST("Н_УЧЕНИКИ"."ГРУППА" AS integer) > 1101;

-- SELECT "Н_ЛЮДИ"."ОТЧЕСТВО", "Н_ОБУЧЕНИЯ"."ЧЛВК_ИД", "Н_УЧЕНИКИ"."ГРУППА",
--        "Н_ЛЮДИ"."ФАМИЛИЯ", "Н_ОБУЧЕНИЯ"."ЧЛВК_ИД", "Н_УЧЕНИКИ"."ИД" FROM "Н_ЛЮДИ"
-- INNER JOIN "Н_ОБУЧЕНИЯ" ON "Н_ЛЮДИ"."ИД" = "Н_ОБУЧЕНИЯ"."ЧЛВК_ИД"
-- INNER JOIN "Н_УЧЕНИКИ" ON "Н_ОБУЧЕНИЯ"."ЧЛВК_ИД" = "Н_УЧЕНИКИ"."ЧЛВК_ИД"
-- WHERE
--     "Н_ЛЮДИ"."ОТЧЕСТВО" > 'Сергеевич' AND
--     "Н_ОБУЧЕНИЯ"."ЧЛВК_ИД" < 112514 AND
--     CAST("Н_УЧЕНИКИ"."ГРУППА" AS integer) > 1101;

-- 3

SELECT count(*) FROM "Н_УЧЕНИКИ"
INNER JOIN "Н_ЛЮДИ" ON "Н_УЧЕНИКИ"."ЧЛВК_ИД" = "Н_ЛЮДИ"."ИД"
WHERE
    "Н_УЧЕНИКИ"."ГРУППА" = '3102' AND
    age("Н_ЛЮДИ"."ДАТА_РОЖДЕНИЯ") < CAST('20 years' AS interval);

SELECT age("Н_ЛЮДИ"."ДАТА_РОЖДЕНИЯ") AS age, * FROM "Н_УЧЕНИКИ"
INNER JOIN "Н_ЛЮДИ" ON "Н_УЧЕНИКИ"."ЧЛВК_ИД" = "Н_ЛЮДИ"."ИД"
WHERE
    "Н_УЧЕНИКИ"."ГРУППА" = '3102' AND
    age("Н_ЛЮДИ"."ДАТА_РОЖДЕНИЯ") < CAST('35 years' AS interval);

-- 4
SELECT "Н_УЧЕНИКИ"."ГРУППА" FROM "Н_УЧЕНИКИ"
WHERE
    "Н_УЧЕНИКИ"."ПЛАН_ИД" IN (
        SELECT "Н_ПЛАНЫ"."ИД" FROM "Н_ПЛАНЫ"
        INNER JOIN "Н_ОТДЕЛЫ" ON "Н_ПЛАНЫ"."ОТД_ИД" = "Н_ОТДЕЛЫ"."ИД"
        WHERE
            "Н_ОТДЕЛЫ"."КОРОТКОЕ_ИМЯ" = 'КТиУ' AND
            ("Н_ПЛАНЫ"."УЧЕБНЫЙ_ГОД" LIKE '%2011' OR
            "Н_ПЛАНЫ"."УЧЕБНЫЙ_ГОД" LIKE '2011%')
    )
GROUP BY "Н_УЧЕНИКИ"."ГРУППА" HAVING count("Н_УЧЕНИКИ"."ГРУППА") = 20;

SELECT "Н_УЧЕНИКИ"."ГРУППА", count("Н_УЧЕНИКИ"."ГРУППА") AS "КОЛИЧЕСТВО" FROM "Н_УЧЕНИКИ"
WHERE
        "Н_УЧЕНИКИ"."ПЛАН_ИД" IN (
        SELECT "Н_ПЛАНЫ"."ИД" FROM "Н_ПЛАНЫ"
        WHERE
                "Н_ПЛАНЫ"."ОТД_ИД" = 703 AND
            (SUBSTRING("Н_ПЛАНЫ"."УЧЕБНЫЙ_ГОД",1,4) = '2011' OR
             SUBSTRING("Н_ПЛАНЫ"."УЧЕБНЫЙ_ГОД",6,9)='2011')
    )
GROUP BY "Н_УЧЕНИКИ"."ГРУППА" HAVING count("Н_УЧЕНИКИ"."ГРУППА") = 20;

SELECT "Н_ОТДЕЛЫ"."ИД" FROM "Н_ОТДЕЛЫ" WHERE "КОРОТКОЕ_ИМЯ" = 'КТиУ';


-- select "Н_ГРУППЫ_ПЛАНОВ"."ГРУППА" from "Н_ЛЮДИ"
-- inner join "Н_УЧЕНИКИ" on "Н_УЧЕНИКИ"."ЧЛВК_ИД" = "Н_ЛЮДИ"."ИД"
-- inner join "Н_ГРУППЫ_ПЛАНОВ" on "Н_ГРУППЫ_ПЛАНОВ"."ГРУППА" = "Н_УЧЕНИКИ"."ГРУППА"
-- inner join "Н_ПЛАНЫ" ON "Н_ГРУППЫ_ПЛАНОВ"."ПЛАН_ИД" = "Н_ПЛАНЫ"."ИД"
-- INNER JOIN "Н_ОТДЕЛЫ" ON "Н_ОТДЕЛЫ"."ИД" = "Н_ПЛАНЫ"."ОТД_ИД"
-- where "Н_ОТДЕЛЫ"."КОРОТКОЕ_ИМЯ" = 'КТиУ' and
--       (SUBSTRING("Н_ПЛАНЫ"."УЧЕБНЫЙ_ГОД",1,4) = '2011' OR
--        SUBSTRING("Н_ПЛАНЫ"."УЧЕБНЫЙ_ГОД",6,9)='2011')
-- group by "Н_ГРУППЫ_ПЛАНОВ"."ГРУППА" having count("Н_ЛЮДИ"."ИД") = 20;

-- 5
SELECT STUDENT_AGE."ГРУППА" AS group_id, avg(STUDENT_AGE.age) AS average_age FROM (
    SELECT "Н_УЧЕНИКИ"."ГРУППА", cast(to_char(age("Н_ЛЮДИ"."ДАТА_РОЖДЕНИЯ"), 'yy') AS int) AS age FROM "Н_УЧЕНИКИ"
    INNER JOIN "Н_ЛЮДИ" ON "Н_УЧЕНИКИ"."ЧЛВК_ИД" = "Н_ЛЮДИ"."ИД"
) AS STUDENT_AGE
GROUP BY STUDENT_AGE."ГРУППА" having avg(STUDENT_AGE.age) < (
    SELECT max(cast(to_char(age("Н_ЛЮДИ"."ДАТА_РОЖДЕНИЯ"), 'yy') AS int)) FROM "Н_УЧЕНИКИ"
    INNER JOIN "Н_ЛЮДИ" ON "Н_УЧЕНИКИ"."ЧЛВК_ИД" = "Н_ЛЮДИ"."ИД"
    WHERE STUDENT_AGE."ГРУППА" = '1100'
);

-- 6
SELECT "Н_УЧЕНИКИ"."ГРУППА", "Н_ЛЮДИ"."ИД", "Н_ЛЮДИ"."ФАМИЛИЯ", "Н_ЛЮДИ"."ИМЯ", "Н_ЛЮДИ"."ОТЧЕСТВО", "Н_УЧЕНИКИ"."П_ПРКОК_ИД" FROM "Н_УЧЕНИКИ"
INNER JOIN "Н_ЛЮДИ" ON "Н_УЧЕНИКИ"."ЧЛВК_ИД" = "Н_ЛЮДИ"."ИД"
INNER JOIN "Н_ПЛАНЫ" ON "Н_УЧЕНИКИ"."ПЛАН_ИД" = "Н_ПЛАНЫ"."ИД"
INNER JOIN "Н_ФОРМЫ_ОБУЧЕНИЯ" ON "Н_ПЛАНЫ"."ФО_ИД" = "Н_ФОРМЫ_ОБУЧЕНИЯ"."ИД"
INNER JOIN "Н_НАПРАВЛЕНИЯ_СПЕЦИАЛ" ON "Н_ПЛАНЫ"."НАПС_ИД" = "Н_НАПРАВЛЕНИЯ_СПЕЦИАЛ"."ИД"
INNER JOIN "Н_НАПР_СПЕЦ" ON "Н_НАПРАВЛЕНИЯ_СПЕЦИАЛ"."НС_ИД" = "Н_НАПР_СПЕЦ"."ИД"
WHERE
    "Н_УЧЕНИКИ"."ПРИЗНАК" = 'отчисл' AND
    "Н_ФОРМЫ_ОБУЧЕНИЯ"."НАИМЕНОВАНИЕ" = 'Заочная' AND
    "Н_НАПР_СПЕЦ"."НАИМЕНОВАНИЕ" = 'Программная инженерия' AND
    "Н_УЧЕНИКИ"."КОНЕЦ" < '2012-09-01';

-- 7
SELECT "Н_ЛЮДИ"."ФАМИЛИЯ", "Н_ЛЮДИ"."ДАТА_РОЖДЕНИЯ" FROM "Н_УЧЕНИКИ"
INNER JOIN "Н_ЛЮДИ" ON "Н_УЧЕНИКИ"."ЧЛВК_ИД" = "Н_ЛЮДИ"."ИД"
WHERE
    "Н_ЛЮДИ"."ФАМИЛИЯ" IN (
        SELECT "Н_ЛЮДИ"."ФАМИЛИЯ" FROM "Н_УЧЕНИКИ"
        INNER JOIN "Н_ЛЮДИ" ON "Н_УЧЕНИКИ"."ЧЛВК_ИД" = "Н_ЛЮДИ"."ИД"
        GROUP BY "Н_ЛЮДИ"."ФАМИЛИЯ"
        HAVING
            count("Н_ЛЮДИ"."ФАМИЛИЯ") > 1
    )
;


SELECT DISTINCT "ФАМИЛИЯ", "ДАТА_РОЖДЕНИЯ" FROM (
SELECT "Н_ЛЮДИ"."ФАМИЛИЯ", "Н_ЛЮДИ"."ДАТА_РОЖДЕНИЯ" FROM "Н_УЧЕНИКИ"
INNER JOIN "Н_ЛЮДИ" ON "Н_УЧЕНИКИ"."ЧЛВК_ИД" = "Н_ЛЮДИ"."ИД"
WHERE
    "Н_ЛЮДИ"."ФАМИЛИЯ" IN (
        SELECT "Н_ЛЮДИ"."ФАМИЛИЯ" FROM "Н_УЧЕНИКИ"
        INNER JOIN "Н_ЛЮДИ" ON "Н_УЧЕНИКИ"."ЧЛВК_ИД" = "Н_ЛЮДИ"."ИД"
        GROUP BY "Н_ЛЮДИ"."ФАМИЛИЯ"
        HAVING
        count("Н_ЛЮДИ"."ФАМИЛИЯ") > 1
    )
) AS T;

SELECT * FROM (
    SELECT "Н_ЛЮДИ"."ФАМИЛИЯ", "Н_ЛЮДИ"."ДАТА_РОЖДЕНИЯ" FROM "Н_УЧЕНИКИ"
    INNER JOIN "Н_ЛЮДИ" ON "Н_УЧЕНИКИ"."ЧЛВК_ИД" = "Н_ЛЮДИ"."ИД"
    WHERE
        "Н_ЛЮДИ"."ФАМИЛИЯ" IN (
            SELECT "Н_ЛЮДИ"."ФАМИЛИЯ" FROM "Н_УЧЕНИКИ"
            INNER JOIN "Н_ЛЮДИ" ON "Н_УЧЕНИКИ"."ЧЛВК_ИД" = "Н_ЛЮДИ"."ИД"
            GROUP BY "Н_ЛЮДИ"."ФАМИЛИЯ"
            HAVING
            count("Н_ЛЮДИ"."ФАМИЛИЯ") > 1
            -- count("Н_ЛЮДИ"."ФАМИЛИЯ" || to_char("Н_ЛЮДИ"."ДАТА_РОЖДЕНИЯ", 'yyyy-mm-dd')) = 1
      )
) AS t1
WHERE "ФАМИЛИЯ" IN (
    SELECT "ФАМИЛИЯ" FROM (
        SELECT "Н_ЛЮДИ"."ФАМИЛИЯ", "Н_ЛЮДИ"."ДАТА_РОЖДЕНИЯ" FROM "Н_УЧЕНИКИ"
                                                                   INNER JOIN "Н_ЛЮДИ" ON "Н_УЧЕНИКИ"."ЧЛВК_ИД" = "Н_ЛЮДИ"."ИД"
        WHERE
              "Н_ЛЮДИ"."ФАМИЛИЯ" IN (
              SELECT "Н_ЛЮДИ"."ФАМИЛИЯ" FROM "Н_УЧЕНИКИ"
                INNER JOIN "Н_ЛЮДИ" ON "Н_УЧЕНИКИ"."ЧЛВК_ИД" = "Н_ЛЮДИ"."ИД"
              GROUP BY "Н_ЛЮДИ"."ФАМИЛИЯ"
              HAVING
                      count("Н_ЛЮДИ"."ФАМИЛИЯ") > 1
              -- count("Н_ЛЮДИ"."ФАМИЛИЯ" || to_char("Н_ЛЮДИ"."ДАТА_РОЖДЕНИЯ", 'yyyy-mm-dd')) = 1
          )
) AS T2
    GROUP BY "ФАМИЛИЯ"
    HAVING count(DISTINCT "ДАТА_РОЖДЕНИЯ") > 1
);

-- dop
SELECT "ФАМИЛИЯ", "ИМЯ", "ОТЧЕСТВО", AGE FROM(
    SELECT "Н_ЛЮДИ"."ФАМИЛИЯ", "Н_ЛЮДИ"."ИМЯ", "Н_ЛЮДИ"."ОТЧЕСТВО", cast(to_char(age("Н_ЛЮДИ"."ДАТА_РОЖДЕНИЯ"), 'yy') AS int) AS AGE FROM "Н_ЛЮДИ"
        INNER JOIN "Н_СЕССИЯ" ON "Н_ЛЮДИ"."ИД" = "Н_СЕССИЯ"."ЧЛВК_ИД"
        INNER JOIN "Н_СОДЕРЖАНИЯ_ЭЛЕМЕНТОВ_СТРОК" ON "Н_СЕССИЯ"."СЭС_ИД" = "Н_СОДЕРЖАНИЯ_ЭЛЕМЕНТОВ_СТРОК"."ИД"
        INNER JOIN "Н_ЭЛЕМЕНТЫ_СТРОК" ON "Н_СОДЕРЖАНИЯ_ЭЛЕМЕНТОВ_СТРОК"."ЭСТ_ИД" = "Н_ЭЛЕМЕНТЫ_СТРОК"."ИД"
        INNER JOIN "Н_ОТДЕЛЫ" ON "Н_ЭЛЕМЕНТЫ_СТРОК"."ОТД_ИД" = "Н_ОТДЕЛЫ"."ИД"
    WHERE "Н_ОТДЕЛЫ"."КОРОТКОЕ_ИМЯ" = 'ВТ'
) AS RES
WHERE AGE = (
    SELECT min(AGE) FROM (
        SELECT cast(to_char(age("Н_ЛЮДИ"."ДАТА_РОЖДЕНИЯ"), 'yy') AS int) AS AGE FROM "Н_ЛЮДИ"
            INNER JOIN "Н_СЕССИЯ" ON "Н_ЛЮДИ"."ИД" = "Н_СЕССИЯ"."ЧЛВК_ИД"
            INNER JOIN "Н_СОДЕРЖАНИЯ_ЭЛЕМЕНТОВ_СТРОК" ON "Н_СЕССИЯ"."СЭС_ИД" = "Н_СОДЕРЖАНИЯ_ЭЛЕМЕНТОВ_СТРОК"."ИД"
            INNER JOIN "Н_ЭЛЕМЕНТЫ_СТРОК" ON "Н_СОДЕРЖАНИЯ_ЭЛЕМЕНТОВ_СТРОК"."ЭСТ_ИД" = "Н_ЭЛЕМЕНТЫ_СТРОК"."ИД"
            INNER JOIN "Н_ОТДЕЛЫ" ON "Н_ЭЛЕМЕНТЫ_СТРОК"."ОТД_ИД" = "Н_ОТДЕЛЫ"."ИД"
            WHERE "Н_ОТДЕЛЫ"."КОРОТКОЕ_ИМЯ" = 'ВТ' AND
                cast(to_char(age("Н_ЛЮДИ"."ДАТА_РОЖДЕНИЯ"), 'yy') AS int) > 0
    ) AS RES
);


SELECT "Н_ЛЮДИ"."ФАМИЛИЯ", "Н_ЛЮДИ"."ИМЯ", "Н_ЛЮДИ"."ОТЧЕСТВО" FROM "Н_ЛЮДИ"
INNER JOIN "Н_СЕССИЯ" ON "Н_ЛЮДИ"."ИД" = "Н_СЕССИЯ"."ЧЛВК_ИД"
INNER JOIN "Н_СОДЕРЖАНИЯ_ЭЛЕМЕНТОВ_СТРОК" ON "Н_СЕССИЯ"."СЭС_ИД" = "Н_СОДЕРЖАНИЯ_ЭЛЕМЕНТОВ_СТРОК"."ИД"
INNER JOIN "Н_ЭЛЕМЕНТЫ_СТРОК" ON "Н_СОДЕРЖАНИЯ_ЭЛЕМЕНТОВ_СТРОК"."ЭСТ_ИД" = "Н_ЭЛЕМЕНТЫ_СТРОК"."ИД"
INNER JOIN "Н_ОТДЕЛЫ" ON "Н_ЭЛЕМЕНТЫ_СТРОК"."ОТД_ИД" = "Н_ОТДЕЛЫ"."ИД"
WHERE "Н_ОТДЕЛЫ"."КОРОТКОЕ_ИМЯ" = 'КТ'
ORDER BY cast(to_char(age("Н_ЛЮДИ"."ДАТА_РОЖДЕНИЯ"), 'yy') AS int)
LIMIT 1;