Skip to content
Open

ok #68

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions homework-1/create_tables.sql
Original file line number Diff line number Diff line change
@@ -1 +1,26 @@
-- SQL-команды для создания таблиц
CREATE TABLE employees
(
employee_id int PRIMARY KEY,
first_name varchar(50) NOT NULL,
last_name varchar(50) NOT NULL,
title varchar(50) NOT NULL,
birth_date date,
notes text
);

CREATE TABLE customers
(
customer_id varchar(50) PRIMARY KEY NOT NULL,
company_name varchar(50) NOT NULL,
contact_name varchar(50) NOT NULL
);

CREATE TABLE orders
(
order_id int PRIMARY KEY NOT NULL,
customer_id varchar(50) REFERENCES customers(customer_id) NOT NULL,
employee_id int REFERENCES employees(employee_id) NOT NULL,
order_date date NOT NULL,
ship_city varchar(50) NOT NULL
);
33 changes: 32 additions & 1 deletion homework-1/main.py
Original file line number Diff line number Diff line change
@@ -1 +1,32 @@
"""Скрипт для заполнения данными таблиц в БД Postgres."""
import psycopg2
import csv
import os

bd = ['employees_data.csv', 'customers_data.csv', 'orders_data.csv']
bd_name = ['employees', 'customers', 'orders']


def add_data_in_bd(bd, bd_name):
"""Скрипт для заполнения данными таблиц в БД Postgres."""
try:
conn = psycopg2.connect(host='localhost', database='north', user='Baxtiyor', password='18071990')
cur = conn.cursor()
for i in range(len(bd)):
with open(os.path.join('north_data', bd[i]), 'r') as csvfile:
header = next(csvfile)
csvreader = csv.reader(csvfile)
for row in csvreader:
placeholders = ', '.join(['%s'] * len(row))
query = f"INSERT INTO {bd_name[i]} VALUES ({placeholders})"
cur.execute(query, row)
conn.commit()
except psycopg2.Error as e:
print("Error executing SQL query:", e)
finally:
if conn is not None:
cur.close()
conn.close()


if __name__ == '__main__':
add_data_in_bd(bd, bd_name)
14 changes: 10 additions & 4 deletions homework-2/filter_sorting.sql
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
-- Напишите запросы, которые выводят следующую информацию:
-- 1. заказы, доставленные в страны France, Germany, Spain (таблица orders, колонка ship_country)
SELECT ...
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 IN ('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
27 changes: 21 additions & 6 deletions homework-2/groupby.sql
Original file line number Diff line number Diff line change
@@ -1,20 +1,35 @@
-- Напишите запросы, которые выводят следующую информацию:
-- 1. заказы, отправленные в города, заканчивающиеся на 'burg'. Вывести без повторений две колонки (город, страна) (см. таблица orders, колонки ship_city, ship_country)

SELECT DISTINCT ship_city, ship_country FROM orders
WHERE ship_city LIKE '%burg'

-- 2. из таблицы orders идентификатор заказа, идентификатор заказчика, вес и страну отгрузки. Заказ отгружен в страны, начинающиеся на 'P'. Результат отсортирован по весу (по убыванию). Вывести первые 10 записей.

SELECT order_id, customer_id, freight, ship_country FROM orders
WHERE ship_country LIKE 'P%' ORDER BY freight DESC LIMIT 10

-- 3. имя, фамилию и телефон сотрудников, у которых в данных отсутствует регион (см таблицу employees)

SELECT first_name, last_name, Home_phone FROM employees
WHERE region IS NULL

-- 4. количество поставщиков (suppliers) в каждой из стран. Результат отсортировать по убыванию количества поставщиков в стране

SELECT country, COUNT(*) AS num_suppliers FROM suppliers
GROUP BY country ORDER BY num_suppliers DESC

-- 5. суммарный вес заказов (в которых известен регион) по странам, но вывести только те результаты, где суммарный вес на страну больше 2750. Отсортировать по убыванию суммарного веса (см таблицу orders, колонки ship_region, ship_country, freight)

SELECT ship_country, SUM(freight)as total_weight from orders
WHERE ship_region IS NOT NULL
GROUP BY ship_country HAVING sum(freight) > 2750 ORDER BY total_weight DESC

-- 6. страны, в которых зарегистрированы и заказчики (customers) и поставщики (suppliers) и работники (employees).

SELECT country FROM Customers
INTERSECT
SELECT country FROM suppliers
INTERSECT
SELECT country FROM employees

-- 7. страны, в которых зарегистрированы и заказчики (customers) и поставщики (suppliers), но не зарегистрированы работники (employees).
SELECT DISTINCT country FROM customers
WHERE NOT EXISTS (SELECT * FROM employees WHERE employees.country = customers.country)
INTERSECT
SELECT DISTINCT country FROM suppliers
WHERE NOT EXISTS (SELECT * FROM employees WHERE employees.country = suppliers.country)
9 changes: 5 additions & 4 deletions homework-2/simple_queries.sql
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
-- Напишите запросы, которые выводят следующую информацию:
-- 1. "имя контакта" и "город" (contact_name, city) из таблицы customers (только эти две колонки)
SELECT ...
SELECT contact_name, city FROM customers

-- 2. идентификатор заказа и разницу между датами формирования (order_date) заказа и его отгрузкой (shipped_date) из таблицы orders

SELECT order_id, shipped_date - order_date FROM orders

-- 3. все города без повторов, в которых зарегистрированы заказчики (customers)

SELECT DISTINCT city FROM customers

-- 4. количество заказов (таблица orders)

SELECT COUNT(order_id) FROM orders

-- 5. количество стран, в которые отгружался товар (таблица orders, колонка ship_country)
SELECT COUNT (DISTINCT ship_country) FROM orders
17 changes: 14 additions & 3 deletions homework-3/queries.sql
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
-- Напишите запросы, которые выводят следующую информацию:
-- 1. Название компании заказчика (company_name из табл. customers) и ФИО сотрудника, работающего над заказом этой компании (см таблицу employees),
-- когда и заказчик и сотрудник зарегистрированы в городе London, а доставку заказа ведет компания United Package (company_name в табл shippers)

SELECT customers.company_name as customer, CONCAT(employees.first_name, ' ', employees.last_name) AS emoloyee FROM customers
JOIN orders USING (customer_id)
JOIN employees USING (employee_id)
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
INNER JOIN suppliers USING (supplier_id)
INNER JOIN categories USING (category_id)
WHERE discontinued = 0 AND units_in_stock < 25 and category_name in('Dairy Products', 'Condiments')
ORDER BY units_in_stock

-- 3. Список компаний заказчиков (company_name из табл customers), не сделавших ни одного заказа

SELECT company_name FROM customers
WHERE customer_id NOT IN (SELECT customer_id FROM orders)

-- 4. уникальные названия продуктов, которых заказано ровно 10 единиц (количество заказанных единиц см в колонке quantity табл order_details)
-- Этот запрос написать именно с использованием подзапроса.
SELECT product_name FROM products
WHERE product_id = ANY (SELECT product_id FROM order_details WHERE quantity = 10)
23 changes: 20 additions & 3 deletions homework-4/alter_northwind.sql
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
-- Подключиться к БД Northwind и сделать следующие изменения:
-- 1. Добавить ограничение на поле unit_price таблицы products (цена должна быть больше 0)

ALTER TABLE products
ADD CONSTRAINT check_unit_price_positive CHECK (unit_price > 0);

-- 2. Добавить ограничение, что поле discontinued таблицы products может содержать только значения 0 или 1

ALTER TABLE products
ADD CONSTRAINT check_discontinued_values CHECK (discontinued IN (0, 1));

-- 3. Создать новую таблицу, содержащую все продукты, снятые с продажи (discontinued = 1)

CREATE TABLE discontinued_products AS
SELECT *
FROM products
WHERE discontinued = 1;

-- 4. Удалить из products товары, снятые с продажи (discontinued = 1)
-- Для 4-го пункта может потребоваться удаление ограничения, связанного с foreign_key. Подумайте, как это можно решить, чтобы связь с таблицей order_details все же осталась.
-- Удаление временного ограничения foreign key
ALTER TABLE order_details
DROP CONSTRAINT fk_order_details_product_id;

-- Удаление товаров со статусом discontinued = 1
DELETE FROM products
WHERE discontinued = 1;

-- Восстановление ограничения foreign key
ALTER TABLE order_details
ADD CONSTRAINT fk_order_details_product_id
FOREIGN KEY (product_id) REFERENCES products (product_id);
26 changes: 20 additions & 6 deletions homework-4/alter_student.sql
Original file line number Diff line number Diff line change
@@ -1,19 +1,33 @@
-- 1. Создать таблицу student с полями student_id serial, first_name varchar, last_name varchar, birthday date, phone varchar

CREATE TABLE student (
student_id SERIAL PRIMARY KEY,
first_name VARCHAR,
last_name VARCHAR,
birthday DATE,
phone VARCHAR
);

-- 2. Добавить в таблицу student колонку middle_name varchar

ALTER TABLE student
ADD COLUMN middle_name VARCHAR;

-- 3. Удалить колонку middle_name

ALTER TABLE student
DROP COLUMN middle_name;

-- 4. Переименовать колонку birthday в birth_date

ALTER TABLE student
RENAME COLUMN birthday TO birth_date;

-- 5. Изменить тип данных колонки phone на varchar(32)

ALTER TABLE student
ALTER COLUMN phone TYPE VARCHAR(32);

-- 6. Вставить три любых записи с автогенерацией идентификатора

INSERT INTO student (first_name, last_name, birth_date, phone) VALUES ('John', 'Doe', '2000-01-01', '1234567890');
INSERT INTO student (first_name, last_name, birth_date, phone) VALUES ('Jane', 'Smith', '2001-02-02', '0987654321');
INSERT INTO student (first_name, last_name, birth_date, phone) VALUES ('Alice', 'Johnson', '1999-03-03', '5551234567');

-- 7. Удалить все данные из таблицы со сбросом идентификатор в исходное состояние
TRUNCATE TABLE student RESTART IDENTITY;

10 changes: 4 additions & 6 deletions homework-5/config.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
from configparser import ConfigParser


def config(filename="database.ini", section="postgresql"):
# create a parser
def config(filename='database.ini', section='postgresql'):
"""Чтение параметров подключения к базе данных из файла конфигурации."""
parser = ConfigParser()
# read config file
parser.read(filename)

db = {}
if parser.has_section(section):
params = parser.items(section)
for param in params:
db[param[0]] = param[1]
else:
raise Exception(
'Section {0} is not found in the {1} file.'.format(section, filename))
raise Exception(f'Section {section} not found in the {filename} file')
return db
62 changes: 54 additions & 8 deletions homework-5/main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import json

import psycopg2

from config import config


Expand Down Expand Up @@ -42,31 +40,79 @@ def main():

def create_database(params, db_name) -> None:
"""Создает новую базу данных."""
pass
try:
conn = psycopg2.connect(**params)
conn.autocommit = True
cur = conn.cursor()
cur.execute(f"CREATE DATABASE {db_name}")
cur.close()
conn.close()
except (Exception, psycopg2.DatabaseError) as error:
print(error)


def execute_sql_script(cur, script_file) -> None:
"""Выполняет скрипт из файла для заполнения БД данными."""

try:
with open(script_file, 'r') as f:
script = f.read()
cur.execute(script)
except (Exception, psycopg2.DatabaseError) as error:
print(error)


def create_suppliers_table(cur) -> None:
"""Создает таблицу suppliers."""
pass
try:
cur.execute("""
CREATE TABLE IF NOT EXISTS suppliers (
supplier_id SERIAL PRIMARY KEY,
name VARCHAR(255),
contact_name VARCHAR(255),
city VARCHAR(255),
country VARCHAR(255)
)
""")
except (Exception, psycopg2.DatabaseError) as error:
print(error)


def get_suppliers_data(json_file: str) -> list[dict]:
"""Извлекает данные о поставщиках из JSON-файла и возвращает список словарей с соответствующей информацией."""
pass
try:
with open(json_file, 'r') as f:
suppliers_data = json.load(f)
return suppliers_data
except (Exception, psycopg2.DatabaseError) as error:
print(error)


def insert_suppliers_data(cur, suppliers: list[dict]) -> None:
"""Добавляет данные из suppliers в таблицу suppliers."""
pass
try:
for supplier in suppliers:
cur.execute("""
INSERT INTO suppliers (name, contact_name, city, country)
VALUES (%s, %s, %s, %s)
""", (supplier['name'], supplier['contact_name'], supplier['city'], supplier['country']))
except (Exception, psycopg2.DatabaseError) as error:
print(error)


def add_foreign_keys(cur, json_file) -> None:
"""Добавляет foreign key со ссылкой на supplier_id в таблицу products."""
pass
try:
cur.execute("""
ALTER TABLE products
ADD COLUMN IF NOT EXISTS supplier_id INT
""")
cur.execute("""
ALTER TABLE products
ADD CONSTRAINT fk_supplier_id
FOREIGN KEY (supplier_id) REFERENCES suppliers(supplier_id)
""")
except (Exception, psycopg2.DatabaseError) as error:
print(error)


if __name__ == '__main__':
Expand Down