diff --git a/homework-1/create_tables.sql b/homework-1/create_tables.sql index 2240c4efb..39b8e2679 100644 --- a/homework-1/create_tables.sql +++ b/homework-1/create_tables.sql @@ -1 +1,29 @@ -- SQL-команды для создания таблиц +CREATE TABLE customers + +( + customer_id varchar(10) PRIMARY KEY, + company_name varchar(100) NOT NULL, + contact_name varchar(100) NOT NULL +); + +# tables 2 +CREATE TABLE employees +( + employee_id int PRIMARY KEY, + first_name varchar(100) NOT NULL, + last_name varchar(100) NOT NULL, + title varchar(100) NOT NULL, + birth_date date, + notes text +); + +# tables 3 +CREATE TABLE orders +( + order_id int PRIMARY KEY, + customer_id varchar(10) REFERENCES customers(customer_id) NOT NULL, + employee_id int REFERENCES employees(employee_id)NOT NULL, + order_date date NOT NULL, + ship_city varchar(100) NOT NULL +) diff --git a/homework-1/main.py b/homework-1/main.py index 5b5e8ffd4..e9895bd92 100644 --- a/homework-1/main.py +++ b/homework-1/main.py @@ -1 +1,63 @@ """Скрипт для заполнения данными таблиц в БД Postgres.""" +import psycopg2 +import csv + +class RecieveDataFromCSV: + """Класс с методом для получения данных из .csv файлов""" + + @staticmethod + def get_data_csv(filename): + all_data = [] + with open(filename, encoding="utf-8") as file: + data_full = csv.DictReader(file) + for data in data_full: + all_data.append(data) + return all_data + + +csv_data_reciever = RecieveDataFromCSV() +customers = csv_data_reciever.get_data_csv('north_data/customers_data.csv') +employees = csv_data_reciever.get_data_csv('north_data/employees_data.csv') +orders = csv_data_reciever.get_data_csv('north_data/orders_data.csv') + +# добавление значения id для работников +employee_id = 1 +for employee_data in employees: + employee_data['employee_id'] = employee_id + employee_id += 1 + +print(customers) + + +conn = psycopg2.connect(host='localhost', database='postgres', user='postgres', password=123) + +try: + """Заполнение таблиц внутри БД north данными""" + with conn: + with conn.cursor() as cur: + for customer in range(len(customers)): + cur.execute('INSERT INTO customers VALUES (%s, %s, %s)', + (customers[customer]['customer_id'], + customers[customer]['company_name'], + customers[customer]['contact_name'])) + + for employee in range(len(employees)): + cur.execute('INSERT INTO employees VALUES (%s, %s, %s, %s, %s, %s)', + (employees[employee]['employee_id'], + employees[employee]['first_name'], + employees[employee]['last_name'], + employees[employee]['title'], + employees[employee]['birth_date'], + employees[employee]['notes'])) + + for order in range(len(orders)): + cur.execute('INSERT INTO orders VALUES (%s, %s, %s, %s, %s)', + (orders[order]['order_id'], + orders[order]['customer_id'], + orders[order]['employee_id'], + orders[order]['order_date'], + orders[order]['ship_city'])) + + +finally: + conn.close() \ No newline at end of file diff --git a/homework-2/filter_sorting.sql b/homework-2/filter_sorting.sql index 3c23694e7..02c5a949c 100644 --- a/homework-2/filter_sorting.sql +++ b/homework-2/filter_sorting.sql @@ -1,14 +1,25 @@ -- Напишите запросы, которые выводят следующую информацию: -- 1. заказы, доставленные в страны France, Germany, Spain (таблица orders, колонка ship_country) -SELECT ... - --- 2. уникальные страны и города, куда отправлялись заказы, отсортировать по странам и городам (таблица orders, колонки ship_country, ship_city) +SELECT * +FROM orders +WHERE ship_country IN ('France', 'Germany', 'Spain'); +-- 2. уникальные города и страны, куда отправлялись заказы, отсортировать по странам и городам (таблица orders, колонки ship_country, ship_city) +SELECT DISTINCT ship_country, ship_city +FROM orders +ORDER BY ship_country, ship_city; -- 3. сколько дней в среднем уходит на доставку товара в Германию (таблица orders, колонки order_date, shipped_date, ship_country) - +SELECT (AVG(shipped_date - order_date)) +FROM orders +WHERE ship_country = 'Germany'; -- 4. минимальную и максимальную цену среди продуктов, не снятых с продажи (таблица products, колонки unit_price, discontinued не равно 1) - +SELECT MIN(unit_price), MAX(unit_price) +FROM products +WHERE discontinued <> 1; -- 5. минимальную и максимальную цену среди продуктов, не снятых с продажи и которых имеется не меньше 20 (таблица products, колонки unit_price, units_in_stock, discontinued не равно 1) +SELECT MIN(unit_price), MAX(unit_price) +FROM products +WHERE discontinued <> 1 and units_in_stock >= 20; \ No newline at end of file diff --git a/homework-2/groupby.sql b/homework-2/groupby.sql index 9568d57ed..3e933d6e1 100644 --- a/homework-2/groupby.sql +++ b/homework-2/groupby.sql @@ -1,20 +1,58 @@ -- Напишите запросы, которые выводят следующую информацию: --- 1. заказы, отправленные в города, заканчивающиеся на 'burg'. Вывести без повторений две колонки (город, страна) (см. таблица orders, колонки ship_city, ship_country) - +-- 1. заказы, отправленные в города, заканчивающиеся на 'burg'. Вывести без повторений две колонки (город, страна) (см. таблица orders, колонки ship_city, ship_country +SELECT DISTINCT ship_city, ship_country +FROM orders +WHERE ship_city +LIKE '%burg'; -- 2. из таблицы orders идентификатор заказа, идентификатор заказчика, вес и страну отгрузки. Заказ отгружен в страны, начинающиеся на 'P'. Результат отсортирован по весу (по убыванию). Вывести первые 10 записей. - - --- 3. фамилию, имя и телефон сотрудников, у которых в данных отсутствует регион (см таблицу employees) - +SELECT order_id, customer_id, freight, ship_country +FROM orders +WHERE ship_country +LIKE 'P%' +ORDER BY freight DESC +LIMIT 10; + +-- 3. фамилию и телефон сотрудников, у которых в данных отсутствует регион (см таблицу employees) +SELECT last_name, home_phone +FROM employees +WHERE region IS NULL; -- 4. количество поставщиков (suppliers) в каждой из стран. Результат отсортировать по убыванию количества поставщиков в стране - +SELECT country, +COUNT(*) +FROM suppliers +GROUP BY country +ORDER BY COUNT(*) +DESC; -- 5. суммарный вес заказов (в которых известен регион) по странам, но вывести только те результаты, где суммарный вес на страну больше 2750. Отсортировать по убыванию суммарного веса (см таблицу orders, колонки ship_region, ship_country, freight) - +SELECT ship_country, SUM(freight) +FROM orders +WHERE ship_region IS NOT NULL +GROUP BY ship_country +HAVING SUM(freight) > 2750 +ORDER BY SUM(freight) +DESC; -- 6. страны, в которых зарегистрированы и заказчики (customers) и поставщики (suppliers) и работники (employees). - +SELECT country +FROM customers +INTERSECT +SELECT country +FROM suppliers +INTERSECT +SELECT country +FROM employees +ORDER BY country; -- 7. страны, в которых зарегистрированы и заказчики (customers) и поставщики (suppliers), но не зарегистрированы работники (employees). +SELECT country +FROM customers +INTERSECT +SELECT country +FROM suppliers +EXCEPT +SELECT country +FROM employees +ORDER BY country; \ No newline at end of file diff --git a/homework-2/simple_queries.sql b/homework-2/simple_queries.sql index 0844a9131..85bee40f8 100644 --- a/homework-2/simple_queries.sql +++ b/homework-2/simple_queries.sql @@ -1,14 +1,21 @@ --- Напишите запросы, которые выводят следующую информацию: --- 1. "имя контакта" и "город" (contact_name, city) из таблицы customers (только эти две колонки) -SELECT ... +-- Напишите запросы, которые выводят следующую информацию +-- 1. "имя контакта" и "город" (contact_name, country) из таблицы customers (только эти две колонки) +SELECT contact_name, country as name_and_country +FROM customers ; -- 2. идентификатор заказа и разницу между датами формирования (order_date) заказа и его отгрузкой (shipped_date) из таблицы orders - +SELECT order_id, shipped_date - order_date +FROM orders; -- 3. все города без повторов, в которых зарегистрированы заказчики (customers) - +SELECT DISTINCT city +FROM customers +ORDER BY city; -- 4. количество заказов (таблица orders) - +SELECT COUNT(*) +FROM orders; -- 5. количество стран, в которые отгружался товар (таблица orders, колонка ship_country) +SELECT COUNT(DISTINCT ship_country) +FROM orders \ No newline at end of file diff --git a/homework-3/queries.sql b/homework-3/queries.sql index 5f2b4173b..8fa4a416d 100644 --- a/homework-3/queries.sql +++ b/homework-3/queries.sql @@ -1,16 +1,32 @@ -- Напишите запросы, которые выводят следующую информацию: -- 1. Название компании заказчика (company_name из табл. customers) и ФИО сотрудника, работающего над заказом этой компании (см таблицу employees), -- когда и заказчик и сотрудник зарегистрированы в городе London, а доставку заказа ведет компания United Package (company_name в табл shippers) - +SELECT DISTINCT customers.company_name, CONCAT(first_name, '/', last_name) +FROM customers +INNER JOIN orders USING(customer_id) +INNER JOIN employees USING(employee_id) +INNER JOIN shippers ON orders.ship_via = shippers.shipper_id +WHERE customers.city = 'London' AND employees.city = 'London' AND shippers.company_name = 'United Package' -- 2. Наименование продукта, количество товара (product_name и units_in_stock в табл products), -- имя поставщика и его телефон (contact_name и phone в табл suppliers) для таких продуктов, -- которые не сняты с продажи (поле discontinued) и которых меньше 25 и которые в категориях Dairy Products и Condiments. -- Отсортировать результат по возрастанию количества оставшегося товара. - +SELECT product_name, units_in_stock, contact_name, phone +FROM products +JOIN suppliers USING(supplier_id) +WHERE discontinued = 0 AND units_in_stock < 25 AND (category_id = 2 OR category_id = 4) +ORDER BY units_in_stock DESC -- 3. Список компаний заказчиков (company_name из табл customers), не сделавших ни одного заказа - +SELECT company_name +FROM customers +LEFT JOIN orders USING(customer_id) +WHERE order_id IS NULL -- 4. уникальные названия продуктов, которых заказано ровно 10 единиц (количество заказанных единиц см в колонке quantity табл order_details) -- Этот запрос написать именно с использованием подзапроса. +SELECT DISTINCT product_name +FROM products +WHERE product_id IN (SELECT product_id FROM order_details WHERE quantity = 10) +--SELECT product_id FROM order_details WHERE quantity = 10 \ No newline at end of file diff --git a/homework-4/alter_northwind.sql b/homework-4/alter_northwind.sql index 852b12178..b934764c6 100644 --- a/homework-4/alter_northwind.sql +++ b/homework-4/alter_northwind.sql @@ -1,12 +1,29 @@ -- Подключиться к БД Northwind и сделать следующие изменения: -- 1. Добавить ограничение на поле unit_price таблицы products (цена должна быть больше 0) +ALTER TABLE public.products ADD CHECK (unit_price >= 0); -- 2. Добавить ограничение, что поле discontinued таблицы products может содержать только значения 0 или 1 +ALTER TABLE public.products ADD CHECK (discontinued IN (0, 1)); -- 3. Создать новую таблицу, содержащую все продукты, снятые с продажи (discontinued = 1) +SELECT * INTO public.discontinued_products +FROM public.products +WHERE discontinued = 1; -- 4. Удалить из products товары, снятые с продажи (discontinued = 1) -- Для 4-го пункта может потребоваться удаление ограничения, связанного с foreign_key. Подумайте, как это можно решить, чтобы связь с таблицей order_details все же осталась. + +-- Удаляем ограничение foreign_key из таблицы order_details +ALTER TABLE order_details DROP CONSTRAINT fk_order_details_products + +--Удаляем из products товары, снятые с продажи (discontinued = 1) +DELETE FROM products WHERE discontinued=1 + +--Удаляем из order_details товары, снятые с продажи (discontinued = 1) +DELETE FROM order_details WHERE product_id IN (SELECT product_id FROM new_products) + +-- Накладываем ограничение foreign_key в таблицу order_details +ALTER TABLE order_details ADD CONSTRAINT fk_order_details_products FOREIGN KEY(product_id) REFERENCES products(product_id) \ No newline at end of file diff --git a/homework-4/alter_student.sql b/homework-4/alter_student.sql index d4f099c60..919e8887f 100644 --- a/homework-4/alter_student.sql +++ b/homework-4/alter_student.sql @@ -1,19 +1,37 @@ --- 1. Создать таблицу student с полями student_id serial, first_name varchar, last_name varchar, birthday date, phone varchar +- 1. Создать таблицу student с полями student_id serial, first_name varchar, last_name varchar, birthday date, phone varchar +CREATE TABLE public.student +( + student_id serial, + first_name varchar, + last_name varchar, + birthday date, + phone varchar +); -- 2. Добавить в таблицу student колонку middle_name varchar +ALTER TABLE public.student ADD COLUMN middle_name varchar; -- 3. Удалить колонку middle_name +ALTER TABLE public.student DROP COLUMN middle_name; -- 4. Переименовать колонку birthday в birth_date +ALTER TABLE public.student RENAME birthday TO birth_day; -- 5. Изменить тип данных колонки phone на varchar(32) +ALTER TABLE public.student ALTER COLUMN phone SET DATA TYPE varchar(32); -- 6. Вставить три любых записи с автогенерацией идентификатора +INSERT INTO public.student (first_name, last_name, birth_day, phone) +VALUES ('Alexandr', 'Abramov', '1995-11-16', +7992), + ('Ivan', 'Ivanov', '2005-04-11', +7992), + ('Petr', 'Petrov', '1989-09-23', +7992); -- 7. Удалить все данные из таблицы со сбросом идентификатор в исходное состояние + +TRUNCATE TABLE public.student RESTART IDENTITY; \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..46f208d60 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,14 @@ +[tool.poetry] +name = "postgres-homeworks" +version = "0.1.0" +description = "" +authors = ["shwwdnl "] +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.11" + + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api"