Решил немного потренироваться с БД, придумал таблицы магазина. Нормализация бд: решил использовать "EAV". Дайте советы по структуре, что нужно исправить и ответьте пожалуйста на некоторые вопросы. Придумайте ещё дополнительные задания по этой БД, для меня. Спойлер: Структура Код (Text): CREATE TABLE category ( id smallserial PRIMARY KEY, name_category char(60) ); INSERT INTO category (name_category) VALUES ('Lenovo'); INSERT INTO category (name_category) VALUES ('Honor'); INSERT INTO category (name_category) VALUES ('Acer'); INSERT INTO category (name_category) VALUES ('Digma'); INSERT INTO category (name_category) VALUES ('Dell'); INSERT INTO category (name_category) VALUES ('HP'); CREATE TABLE diagonal ( id smallserial PRIMARY KEY, size char(10) ); INSERT INTO diagonal (size) VALUES ('15.6'); INSERT INTO diagonal (size) VALUES ('17.3'); INSERT INTO diagonal (size) VALUES ('14'); INSERT INTO diagonal (size) VALUES ('14.1'); CREATE TABLE screen ( id smallserial PRIMARY KEY, permission char(20) ); INSERT INTO screen (permission) VALUES ('1920х1080'); INSERT INTO screen (permission) VALUES ('1600х900'); INSERT INTO screen (permission) VALUES ('1366х768'); CREATE TABLE cpu ( id smallserial PRIMARY KEY, cpu_name char(40) ); INSERT INTO cpu (cpu_name) VALUES ('AMD Ryzen 5 5600H'); INSERT INTO cpu (cpu_name) VALUES ('Intel Core i3'); INSERT INTO cpu (cpu_name) VALUES ('AMD 3020e'); INSERT INTO cpu (cpu_name) VALUES ('Intel Core i5'); INSERT INTO cpu (cpu_name) VALUES ('Intel Celeron N4500'); INSERT INTO cpu (cpu_name) VALUES ('AMD Ryzen 3'); INSERT INTO cpu (cpu_name) VALUES ('Intel Pentium J3710'); INSERT INTO cpu (cpu_name) VALUES ('Intel Core i7'); INSERT INTO cpu (cpu_name) VALUES ('Intel Celeron 4205U'); CREATE TABLE ram ( id smallserial PRIMARY KEY, quantity_ram char(40) ); INSERT INTO ram (quantity_ram) VALUES ('8'); INSERT INTO ram (quantity_ram) VALUES ('16'); INSERT INTO ram (quantity_ram) VALUES ('4'); CREATE TABLE gpu ( id smallserial PRIMARY KEY, gpu_name char(60) ); INSERT INTO gpu(gpu_name) VALUES ('NVIDIA GeForce RTX 3050'); INSERT INTO gpu(gpu_name) VALUES ('Intel UHD Graphics'); INSERT INTO gpu(gpu_name) VALUES ('AMD Radeon'); INSERT INTO gpu(gpu_name) VALUES ('Intel UHD Graphics'); INSERT INTO gpu(gpu_name) VALUES ('Intel Iris Xe graphics'); INSERT INTO gpu(gpu_name) VALUES ('Intel HD Graphics 405'); INSERT INTO gpu(gpu_name) VALUES ('NVIDIA GeForce RTX 3060'); CREATE TABLE disk ( id smallserial PRIMARY KEY, capacity_disk char(60) ); INSERT INTO disk(capacity_disk) VALUES ('256 ГБ'); INSERT INTO disk(capacity_disk) VALUES ('128 ГБ'); INSERT INTO disk(capacity_disk) VALUES ('512 ГБ'); INSERT INTO disk(capacity_disk) VALUES ('1000 ГБ'); CREATE TABLE system ( id smallserial PRIMARY KEY, system_name char(40) ); INSERT INTO system(system_name) VALUES ('noOS'); INSERT INTO system(system_name) VALUES ('Free DOS'); INSERT INTO system(system_name) VALUES ('Windows 10 Home'); INSERT INTO system(system_name) VALUES ('Eshell'); INSERT INTO system(system_name) VALUES ('Linux'); INSERT INTO system(system_name) VALUES ('Windows 11 Home'); CREATE TABLE laptops ( id smallserial PRIMARY KEY, name_notebook char(40), price real, diagonal_id numeric, screen_id numeric, cpu_id numeric, ram_id numeric, gpu_id numeric, disk_id numeric, system_id numeric, category_id numeric NOT NULL ); Спойлер: Вывод главной таблицы Код (Text): id name_notebook price diagonal_id screen_id cpu_id ram_id gpu_id disk_id system_id category_id 1 Lenovo IP Gaming 3 15ACH6 70 990 1 1 1 1 1 1 1 1 2 Lenovo IdeaPad S145-15IIL 33 990 1 1 2 1 2 2 2 1 3 Lenovo IdeaPad 3 17ADA05 41 290 2 2 3 1 3 1 1 1 4 Honor MagicBook X14 45 990 3 1 2 1 4 1 3 2 5 Acer Aspire 3 A317-33-C2SS 29 990 2 2 5 3 4 2 3 3 6 Acer Aspire 3 A317-52-332C 35 190 2 2 2 3 4 1 4 3 7 Acer Nitro 5 AN515-55-57HB 84 990 1 1 4 2 1 3 4 3 8 Acer Aspire 3 A315-23-R5HA 32 790 1 1 6 1 3 2 4 3 9 Acer Aspire 3 A315-56-34DD 38 390 1 1 2 1 4 4 4 3 10 Digma EVE 14 P416 19 790 3 1 7 3 6 2 3 4 11 Ноутбук DELL G15 5510 110 990 1 1 8 2 7 3 5 5 12 DELL Vostro 3515 43 570 1 1 6 1 3 1 6 5 13 DELL Inspiron 3583 25 590 1 3 9 3 4 2 5 5 Спойлер: Вывести все ноутбуки: SELECT name_notebook, price, size, permission, cpu_name, quantity_ram, gpu_name, capacity_disk, system_name FROM laptops JOIN diagonal ON diagonal_id=diagonal.id JOIN screen ON screen_id=screen.id JOIN cpu ON cpu_id=cpu.id JOIN ram ON ram_id=ram.id JOIN gpu ON gpu_id=gpu.id JOIN disk ON disk_id=disk.id JOIN system ON system_id=system.id ORDER BY laptops.id; Спойлер: Вывести все ноутбуки, у которых ОЗУ 8 ГБ: решил сделать по полю ram.quantity_ram или лучше по id? Код (Text): SELECT name_notebook, price, size, permission, cpu_name, quantity_ram, gpu_name, capacity_disk, system_name FROM laptops JOIN diagonal ON diagonal_id=diagonal.id JOIN screen ON screen_id=screen.id JOIN cpu ON cpu_id=cpu.id JOIN ram ON ram_id=ram.id JOIN gpu ON gpu_id=gpu.id JOIN disk ON disk_id=disk.id JOIN system ON system_id=system.id GROUP BY laptops.id, name_notebook, price, size, permission, cpu_name, quantity_ram, gpu_name, capacity_disk, system_name HAVING ram.quantity_ram = '8'; Спойлер: Вывести ноутбуки с ОЗУ 16 и 4 Код (Text): SELECT name_notebook FROM laptops JOIN ram ON laptops.ram_id = ram.id AND laptops.ram_id IN (2,3) GROUP BY name_notebook, ram.quantity_ram; Код (Text): SELECT name_notebook,ram.quantity_ram FROM laptops LEFT OUTER JOIN ram ON laptops.ram_id = ram.id AND ram.quantity_ram = '8' GROUP BY name_notebook, ram.quantity_ram HAVING ram.quantity_ram = '8'; Я так понял, что при использовании HAVING, поля с NULL игнорируются? SELECT name_notebook,ram.quantity_ram FROM laptops LEFT OUTER JOIN ram ON laptops.ram_id = ram.id AND ram.quantity_ram = '8' GROUP BY name_notebook, ram.quantity_ram; Спойлер: Вывести все ноутбуки, у которых ОЗУ 8 ГБ и все остальные Код (Text): SELECT name_notebook, ram.quantity_ram FROM laptops LEFT OUTER JOIN ram ON laptops.ram_id = ram.id AND ram.quantity_ram = '8' GROUP BY name_notebook, ram.quantity_ram; Здесь за основу будет таблица "ram" и к ней уже присоединяется таблица "laptops", потому что RIGHT JOIN Почему, если убрать HAVING то будут лишние поля, если я указал, что нужно только ram.quantity_ram = '16'? Код (Text): SELECT name_notebook, ram.quantity_ram FROM laptops RIGHT OUTER JOIN ram ON laptops.ram_id = ram.id AND ram.quantity_ram = '16' GROUP BY name_notebook, ram.quantity_ram HAVING ram.quantity_ram = '16'; Спойлер: Количество ноутбуков с определённым ОЗУ: Код (Text): SELECT ram.quantity_ram, count(ram.quantity_ram) FROM laptops JOIN ram ON laptops.ram_id = ram.id GROUP BY ram.quantity_ram; Спойлер: Определить к какой категории относится ноутбук Почему для GROUP BY надо указывать теже поля, что и для SELECT? Код (Text): SELECT name_notebook, category.name_category FROM laptops JOIN category ON category.id = laptops.category_id GROUP BY name_notebook, category.name_category; Спойлер: Количество товаров в каждой категории. Почему, если для "count" указать "name_category", то те категории, которые пустые, в нгих посчитается 1? Код (Text): SELECT name_category, count(name_category) FROM category LEFT JOIN laptops ON category.id = laptops.category_id GROUP BY category.name_category; А вот так, уже правильно считает. Код (Text): SELECT name_category, count(laptops.category_id) FROM category LEFT JOIN laptops ON category.id = laptops.category_id GROUP BY category.name_category; --- Добавлено ---
Спойлер: Наполнение БД Код (Text): INSERT INTO laptops ( name_notebook, price, diagonal_id, screen_id, cpu_id, ram_id, gpu_id, disk_id, system_id, category_id ) VALUES ( 'Lenovo IP Gaming 3 15ACH6', '70990', '1', '1', '1', '1', '1', '1', '1', '1' ); INSERT INTO laptops ( name_notebook, price, diagonal_id, screen_id, cpu_id, ram_id, gpu_id, disk_id, system_id, category_id ) VALUES ( 'Lenovo IdeaPad S145-15IIL', '33990', '1', '1', '2', '1', '2', '2', '2', '1' ); INSERT INTO laptops ( name_notebook, price, diagonal_id, screen_id, cpu_id, ram_id, gpu_id, disk_id, system_id, category_id ) VALUES ( 'Lenovo IdeaPad 3 17ADA05', '41290', '2', '2', '3', '1', '3', '1', '1', '1' ); INSERT INTO laptops ( name_notebook, price, diagonal_id, screen_id, cpu_id, ram_id, gpu_id, disk_id, system_id, category_id ) VALUES ( 'Honor MagicBook X14', '45990', '3', '1', '2', '1', '4', '1', '3', '2, ); INSERT INTO laptops ( name_notebook, price, diagonal_id, screen_id, cpu_id, ram_id, gpu_id, disk_id, system_id, category_id ) VALUES ( 'Acer Aspire 3 A317-33-C2SS', '29990', '2', '2', '5', '3', '4', '2', '3', '3' ); INSERT INTO laptops ( name_notebook, price, diagonal_id, screen_id, cpu_id, ram_id, gpu_id, disk_id, system_id, category_id ) VALUES ( 'Acer Aspire 3 A317-52-332C', '35190', '2', '2', '2', '3', '4', '1', '4', '3' ); INSERT INTO laptops ( name_notebook, price, diagonal_id, screen_id, cpu_id, ram_id, gpu_id, disk_id, system_id, category_id ) VALUES ( 'Acer Nitro 5 AN515-55-57HB', '84990', '1', '1', '4', '2', '1', '3', '4', '3' ); INSERT INTO laptops ( name_notebook, price, diagonal_id, screen_id, cpu_id, ram_id, gpu_id, disk_id, system_id, category_id ) VALUES ( 'Acer Aspire 3 A315-23-R5HA', '32790', '1', '1', '6', '1', '3', '2', '4', '3, ); INSERT INTO laptops ( name_notebook, price, diagonal_id, screen_id, cpu_id, ram_id, gpu_id, disk_id, system_id, category_id ) VALUES ( 'Acer Aspire 3 A315-56-34DD', '38390', '1', '1', '2', '1', '4', '4', '4', '3' ); INSERT INTO laptops ( name_notebook, price, diagonal_id, screen_id, cpu_id, ram_id, gpu_id, disk_id, system_id, category_id ) VALUES ( 'Digma EVE 14 P416', '19790', '3', '1', '7', '3', '6', '2', '3', '4' ); INSERT INTO laptops ( name_notebook, price, diagonal_id, screen_id, cpu_id, ram_id, gpu_id, disk_id, system_id, category_id ) VALUES ( 'Ноутбук DELL G15 5510', '110990', '1', '1', '8', '2', '7', '3', '5', '5' ); INSERT INTO laptops ( name_notebook, price, diagonal_id, screen_id, cpu_id, ram_id, gpu_id, disk_id, system_id, category_id ) VALUES ( 'DELL Vostro 3515 ', '43570', '1', '1', '6', '1', '3', '1', '6', '5' ); INSERT INTO laptops ( name_notebook, price, diagonal_id, screen_id, cpu_id, ram_id, gpu_id, disk_id, system_id, category_id ) VALUES ( 'DELL Inspiron 3583', '25590', '1', '3', '9', '3', '4', '2', '5', '5' );