Конфликты

CREATE DATABASE `sql` # Создаём базу данных с именем sql
 
INSERT INTO `my_byers`(`age`, `name`, `price`) VALUES (30, 'Bob', 450), (20, 'Steve', 500), (13, 'Rob', 50), (43, 'Jane', 300) # Ничего необычного, просто добавляем данные в поля таблички my_byers
 
INSERT INTO `my_byers`(`id`, `age`, `name`, `price`) VALUES (2, 43, 'Diana', 444) ON DUPLICATE KEY UPDATE `age` = 43 # ON - обработчик конфликта, DUPLICATE - сам конфликт

Аналогичный запрос для конфликта в PostgreSQL

INSERT INTO my_byers(id, age, name, price) VALUES (2, 43, 'Diana', 444) ON CONFLICT(id) DO UPDATE SET age = 43

Внешние ключи

CREATE TABLE parent ( id INT NOT NULL, PRIMARY KEY(id)) ENGINE=INNODB # Создаём таблицу parent на движке INNODB, а не на MyISAM, так как вторая не поддерживает ссылки на данные из других таблиц
 
CREATE TABLE сhild ( # Создаём таблицу child 
 	id INT NOT NULL,
    parent_id INT, 
	PRIMARY KEY(id), # id должен быть уникальным
    FOREIGN KEY (parent_id) # Создаём родительское поле
    	REFERENCES parent(id) # Ссылаемся на значение id из таблички parent
    	ON DELETE CASCADE # Обрабатываем конфликт: если id будет удалён, то и parent_id будет удалён
) ENGINE=INNODB
 
INSERT INTO `parent`(`id`) VALUES (1), (2), (3) # Добавляем записи в parent в поле id

Практика

CREATE TABLE users ( # Создаём табличку users, где мы будем хранить информацию о покупателях 
	id INT (11) NOT NULL AUTO_INCREMENT,
	age INT(5) NOT NULL,
	name VARCHAR(50) NOT NULL,
	PRIMARY KEY (id) # id должен быть уникальным
) ENGINE=INNODB # По умолчанию и так ставится InnoDB, но лучше дополнительно указать 
 
INSERT INTO `users`(`age`, `name`) VALUES (16, 'Tigran'), (47, 'Ki Hun'), (42, 'Sang Woo'), (25, 'Sae Byeok'), (26, 'Jimmy') # Добавляем данные в табличку users для полей age и name (создаём покупателей)
 
CREATE TABLE items ( # Создаём табличку items, где мы будем хранить информацию о товарах
	id INT (11) NOT NULL AUTO_INCREMENT,
	price INT(5) NOT NULL,
	name VARCHAR(50) NOT NULL,
	PRIMARY KEY (id)
) ENGINE=INNODB
 
INSERT INTO `items`(`price`, `name`) VALUES (999, 'iPhone'), (299, 'iPad'), (49, 'iPod Shuffle'), (149, 'Apple TV'), (10, 'EarPodes') # Добавляем данные в табличку items для полей price и name (создаём товары)
 
CREATE TABLE orders (  # Создаём табличку orders, где мы будем хранить информацию о заказах
	id INT (11) NOT NULL AUTO_ INCREMENT,
	userId INT(11) NOT NULL,
	itemId INT(11) NOT NULL,
	PRIMARY KEY (id),
	FOREIGN KEY (userId) REFERENCES users(id), # userId ссылается на пользователя, который что-то купил
	FOREIGN KEY (itemId) REFERENCES items (id) # itemId ссылается на товар, который был куплен
) ENGINE=INNODB
 
INSERT INTO `orders` (`id`, `userId`, `itemId`) VALUES (NULL, '5', '1'), (NULL, '2', '5'); # Например, Jimmy купил iPhone, а  Ki Hun купил EarPodes
 
ALTER TABLE `items` ADD PRIMARY(`id`) # Добавление внешнего (первичного) ключа для таблицы items
ALTER TABLE `items` DROP PRIMARY(`id`) # Удаление внешнего (первичного) ключа для таблицы items

Объединения

Сырой вариант 1.0

  • Прописываем команды в табличке orders
  • Выводим все заказы и всех пользователей, которые осуществили эти заказы
    • При этом выводится и всякий мусор в виде id обоих таблиц, а также userId и itemId
SELECT * FROM `orders`
JOIN `items` ON orders.itemId = items.id # Если id заказанного товара равен id обычного товара
JOIN `users` ON orders.userId = users.id; # Если id заказавшего пользователя равен id обычного пользователя

![[CleanShot 2025-02-21 at 13.51.25@2x.png|500]]

Делаем красивее 2.0

SELECT users.name AS User, items.name AS Item FROM `orders` # Здесь сужаем выборку, оставляем только имена пользователей и имена товаров
JOIN `users` ON users.id = orders.userId
JOIN `items` ON items.id = orders.itemId

![[CleanShot 2025-02-21 at 14.03.59@2x.png|200]]

Делаем и красиво, и полезно 3.0

SELECT users.name AS 'Имя покупателя', items.name AS 'Название товара', items.price AS 'Цена товара 'FROM `orders` # Добавлем отображение цены товара
JOIN `users` ON users.id = orders.userId
JOIN `items` ON items.id = orders.itemId

![[CleanShot 2025-02-21 at 14.14.50@2x.png|400]]

Выводим общую сумму покупок 3.1

SELECT users.name AS 'Имя покупателя', SUM(items.price) AS 'Общая стоимость' FROM `orders`
JOIN `users` ON users.id = orders.userId
JOIN `items` ON items.id = orders.itemId
GROUP BY orders.userId

![[CleanShot 2025-02-21 at 14.22.20@2x.png|300]]

Выводим покупателей, которые купили больше определённой суммы 3.2

SELECT users.name AS 'Имя покупателя', SUM(items.price) AS 'Общая стоимость' FROM `orders`
JOIN `users` ON users.id = orders.userId
JOIN `items` ON items.id = orders.itemId
GROUP BY orders.userId
HAVING SUM(items.price) > 100

![[CleanShot 2025-02-21 at 14.25.51@2x.png|300]]

Итоговый вариант c максимальным юзабилити 4.0

SELECT CONCAT('Имя пользователя: ', users.name, ' . Общая стоимость: ', SUM(items.price)) AS 'Полная информация'
FROM `orders`
JOIN `users` ON users.id = orders.userId
JOIN `items` ON items.id = orders.itemId
GROUP BY orders.userId
HAVING SUM(items.price) > 100 
\```
![[CleanShot 2025-02-21 at 14.32.12@2x.png|400]]