Narzędzia użytkownika

Narzędzia witryny


notatki:bazy_danych

Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Poprzednia rewizja po obu stronachPoprzednia wersja
Nowa wersja
Poprzednia wersja
notatki:bazy_danych [2025/05/13 11:41] administratornotatki:bazy_danych [2025/05/16 17:25] (aktualna) administrator
Linia 1: Linia 1:
-====== Tworzenie zapytań SQL w MySQL ======+====== MySQL: Wstęp projekt bazy Sklep ====== 
 + 
 +Możesz podążać za tutorialem poprzez stronę: https://wiki.ostrowski.net.pl/php_mysql/sklep.php
  
 W tym artykule wykorzystamy przykładową bazę danych sklepu internetowego z trzema tabelami: klienci, towary i zamówienia. Przedstawimy definicje tabel w SQL oraz dodamy po 10 przykładowych rekordów do każdej z nich. Następnie omówimy różne rodzaje zapytań na tych danych, w tym: W tym artykule wykorzystamy przykładową bazę danych sklepu internetowego z trzema tabelami: klienci, towary i zamówienia. Przedstawimy definicje tabel w SQL oraz dodamy po 10 przykładowych rekordów do każdej z nich. Następnie omówimy różne rodzaje zapytań na tych danych, w tym:
Linia 14: Linia 16:
 == Tabele i przykładowe dane == == Tabele i przykładowe dane ==
 Zacznijmy od zdefiniowania struktury bazy danych sklepu. Utworzymy trzy tabele:  Zacznijmy od zdefiniowania struktury bazy danych sklepu. Utworzymy trzy tabele: 
-<code sql+<WRAP right 25%> 
 +{{:notatki:pasted:20250513-114421.png?300}}\\ 
 +Po wykonaniu skryptu powinniśmy uzyskać coś takiego 
 +</WRAP>
 <code sql> <code sql>
 CREATE TABLE klienci ( CREATE TABLE klienci (
Linia 49: Linia 54:
 ); );
 </code> </code>
 +<WRAP right 25%>
 +{{:notatki:pasted:20250513-120303.png}}\\
 +Schemat bazy wygenerowany za pomocą narzedzia [[https://www.adminer.org/pl/|Adminer]]
 +</WRAP>
 Wyjaśnienia: Wyjaśnienia:
  
Linia 71: Linia 80:
  
 Następnie dodamy przykładowe rekordy do każdej tabeli:  Następnie dodamy przykładowe rekordy do każdej tabeli: 
 +<WRAP right 25%>
 +{{:notatki:pasted:20250513-114628.png}}\\
 +Po wykonaniu powinniśmy uzyskać coś takiego
 +</WRAP>
 <code sql>  <code sql> 
 INSERT INTO klienci  INSERT INTO klienci 
Linia 86: Linia 99:
 (10,'Magdalena','Jankowska','Poznań',44); (10,'Magdalena','Jankowska','Poznań',44);
 </code>  </code> 
 +<WRAP right 25%>
 +{{:notatki:pasted:20250513-114812.png}}\\
 +Po wykonaniu powinniśmy uzyskać coś takiego
 +</WRAP>
 <code sql>  <code sql> 
 INSERT INTO towary  INSERT INTO towary 
Linia 101: Linia 118:
 (10,'Książka \"SQL dla początkujących\"','Książki',79.90); (10,'Książka \"SQL dla początkujących\"','Książki',79.90);
 </code>  </code> 
 +<WRAP right 25%>
 +{{:notatki:pasted:20250513-115000.png}}\\
 +Po wykonaniu powinniśmy uzyskać coś takiego
 +</WRAP>
 <code sql>  <code sql> 
 INSERT INTO zamowienia  INSERT INTO zamowienia 
Linia 122: Linia 143:
  
 Podstawowym zapytaniem służącym do pobierania danych jest SELECT. Pozwala ono wybrać jedną lub więcej kolumn z tabeli. Najprostsze zapytanie SELECT zwraca wszystkie kolumny i wiersze danej tabeli. Przykładowo: <code sql> SELECT * FROM klienci; </code> Podstawowym zapytaniem służącym do pobierania danych jest SELECT. Pozwala ono wybrać jedną lub więcej kolumn z tabeli. Najprostsze zapytanie SELECT zwraca wszystkie kolumny i wiersze danej tabeli. Przykładowo: <code sql> SELECT * FROM klienci; </code>
 +{{:notatki:pasted:20250513-115136.png}}
  
 to zapytanie pobiera wszystkie dane z tabeli klienci. Często potrzebujemy jednak filtrować rekordy według pewnych kryteriów. Służy do tego klauzula WHERE, np. aby wybrać klientów z konkretnego miasta: <code sql> SELECT * FROM klienci WHERE miasto = 'Warszawa'; </code> to zapytanie pobiera wszystkie dane z tabeli klienci. Często potrzebujemy jednak filtrować rekordy według pewnych kryteriów. Służy do tego klauzula WHERE, np. aby wybrać klientów z konkretnego miasta: <code sql> SELECT * FROM klienci WHERE miasto = 'Warszawa'; </code>
 +{{:notatki:pasted:20250513-115157.png}}
  
 Możemy też ograniczać liczbę wyników i ich kolejność. Klauzula ORDER BY sortuje wyniki względem podanych kolumn (domyślnie rosnąco), natomiast LIMIT ogranicza liczbę zwracanych wierszy Możemy też ograniczać liczbę wyników i ich kolejność. Klauzula ORDER BY sortuje wyniki względem podanych kolumn (domyślnie rosnąco), natomiast LIMIT ogranicza liczbę zwracanych wierszy
  
 Przykłady: <code sql> SELECT imie,nazwisko,wiek FROM klienci WHERE wiek > 30 ORDER BY wiek DESC LIMIT 3; </code> Przykłady: <code sql> SELECT imie,nazwisko,wiek FROM klienci WHERE wiek > 30 ORDER BY wiek DESC LIMIT 3; </code>
 +{{:notatki:pasted:20250513-115224.png}}
  
 Powyższe zapytanie wybiera imiona, nazwiska i wiek klientów starszych niż 30 lat, sortuje je malejąco według wieku i ogranicza wynik do trzech pierwszych rekordów. Powyższe zapytanie wybiera imiona, nazwiska i wiek klientów starszych niż 30 lat, sortuje je malejąco według wieku i ogranicza wynik do trzech pierwszych rekordów.
Linia 151: Linia 175:
 W naszym przykładzie, aby uzyskać listę zamówień wraz z danymi klienta i nazwy towaru, możemy połączyć wszystkie trzy tabele. Przykład zagnieżdżonego łączenia (łączenie wielu tabel):  W naszym przykładzie, aby uzyskać listę zamówień wraz z danymi klienta i nazwy towaru, możemy połączyć wszystkie trzy tabele. Przykład zagnieżdżonego łączenia (łączenie wielu tabel): 
  
-<code sql> SELECT k.imie, k.nazwisko, t.nazwa AS nazwa_towaru, z.ilosc, z.data +<code sql>  
 +SELECT k.imie, k.nazwisko, t.nazwa AS nazwa_towaru, z.ilosc, z.data 
 FROM zamowienia z  FROM zamowienia z 
 INNER JOIN klienci k ON z.id_klienta = k.id_klienta  INNER JOIN klienci k ON z.id_klienta = k.id_klienta 
 INNER JOIN towary t ON z.id_towaru = t.id_towaru;  INNER JOIN towary t ON z.id_towaru = t.id_towaru; 
 </code> </code>
 +{{:notatki:pasted:20250513-115309.png}}
  
 Wynik tego zapytania będzie zawierał imię i nazwisko klienta, nazwę zamówionego towaru, ilość i datę dla każdego zamówienia. Wynik tego zapytania będzie zawierał imię i nazwisko klienta, nazwę zamówionego towaru, ilość i datę dla każdego zamówienia.
Linia 169: Linia 195:
 SELECT k.id_klienta, k.imie, z.id_zamowienia  SELECT k.id_klienta, k.imie, z.id_zamowienia 
 FROM klienci k  FROM klienci k 
-LEFT JOIN zamowienia z ON k.id_klienta = z.id_klienta; </code>+LEFT JOIN zamowienia z ON k.id_klienta = z.id_klienta;  
 +</code> 
 +{{:notatki:pasted:20250513-115336.png}}
  
 W efekcie zobaczymy, że klienci bez zamówień (np. o id 8, 9, 10) będą mieli NULL w kolumnie id_zamowienia. RIGHT JOIN działa podobnie, tylko względem prawej tabeli:  W efekcie zobaczymy, że klienci bez zamówień (np. o id 8, 9, 10) będą mieli NULL w kolumnie id_zamowienia. RIGHT JOIN działa podobnie, tylko względem prawej tabeli: 
Linia 178: Linia 206:
 ON z.id_klienta = k.id_klienta;  ON z.id_klienta = k.id_klienta; 
 </code> </code>
 +{{:notatki:pasted:20250513-115401.png}}
  
 Podsumowując: Podsumowując:
Linia 194: Linia 223:
 GROUP BY miasto;  GROUP BY miasto; 
 </code> </code>
 +{{:notatki:pasted:20250513-115426.png}}
  
 Wynik pokaże liczbę klientów z Warszawy, Krakowa, itp. Funkcje agregujące: Wynik pokaże liczbę klientów z Warszawy, Krakowa, itp. Funkcje agregujące:
Linia 208: Linia 238:
 GROUP BY id_klienta;  GROUP BY id_klienta; 
 </code> </code>
 +{{:notatki:pasted:20250513-115446.png}}
  
 Innym przykładem jest zbadanie średniej ceny wszystkich produktów:  Innym przykładem jest zbadanie średniej ceny wszystkich produktów: 
Linia 214: Linia 245:
 FROM towary;  FROM towary; 
 </code> </code>
 +{{:notatki:pasted:20250513-115501.png}}
  
 Funkcje agregujące ignorują wartości NULL, a gdy użyjemy ich bez klauzuli GROUP BY, traktowane są jak pojedyncza grupa obejmująca wszystkie wiersze. Funkcje agregujące ignorują wartości NULL, a gdy użyjemy ich bez klauzuli GROUP BY, traktowane są jak pojedyncza grupa obejmująca wszystkie wiersze.
Linia 230: Linia 262:
 INSERT INTO klienci (id_klienta, imie, nazwisko, miasto, wiek) VALUES (11,'Karolina','Mazur','Gdynia',29);  INSERT INTO klienci (id_klienta, imie, nazwisko, miasto, wiek) VALUES (11,'Karolina','Mazur','Gdynia',29); 
 </code>  </code> 
 +{{:notatki:pasted:20250513-115533.png}}
 <code sql>  <code sql> 
 -- Zmiana miasta klienta o id 2  -- Zmiana miasta klienta o id 2 
 UPDATE klienci SET miasto = 'Gdańsk' WHERE id_klienta = 2;  UPDATE klienci SET miasto = 'Gdańsk' WHERE id_klienta = 2; 
 </code>  </code> 
 +{{:notatki:pasted:20250513-115602.png}}
 <code sql>  <code sql> 
 -- Usunięcie klienta o id 10  -- Usunięcie klienta o id 10 
 DELETE FROM klienci WHERE id_klienta = 10;  DELETE FROM klienci WHERE id_klienta = 10; 
 </code> </code>
 +{{:notatki:pasted:20250513-115748.png}}
  
 Każde z tych zapytań ma swoje szczegóły: np. UPDATE i DELETE BEZ klauzuli WHERE zmodyfikują/usuną wszystkie wiersze tabeli, dlatego zawsze należy doprecyzować warunek. Każde z tych zapytań ma swoje szczegóły: np. UPDATE i DELETE BEZ klauzuli WHERE zmodyfikują/usuną wszystkie wiersze tabeli, dlatego zawsze należy doprecyzować warunek.
Linia 250: Linia 285:
 WHERE cena > (SELECT AVG(cena) FROM towary);  WHERE cena > (SELECT AVG(cena) FROM towary); 
 </code> </code>
 +{{:notatki:pasted:20250513-115809.png}}
  
 To zapytanie zwraca produkty, których cena jest większa niż średnia cena wszystkich produktów. Najpierw wykonujemy podzapytanie (SELECT AVG(cena) FROM towary), które oblicza średnią cenę, a następnie główne zapytanie wybiera towary o cenie większej od tej wartości. To zapytanie zwraca produkty, których cena jest większa niż średnia cena wszystkich produktów. Najpierw wykonujemy podzapytanie (SELECT AVG(cena) FROM towary), które oblicza średnią cenę, a następnie główne zapytanie wybiera towary o cenie większej od tej wartości.
Linia 273: Linia 309:
 CALL LiczbaZamowienDlaKlienta(1);  CALL LiczbaZamowienDlaKlienta(1); 
 </code> </code>
 +{{:notatki:pasted:20250513-115841.png}}
  
 Procedury składowane ułatwiają wielokrotne wykonywanie tych samych operacji na bazie i mogą zwracać zestawy wyników lub dane wyjściowe. Procedury składowane ułatwiają wielokrotne wykonywanie tych samych operacji na bazie i mogą zwracać zestawy wyników lub dane wyjściowe.
Linia 278: Linia 315:
 == Podsumowanie == == Podsumowanie ==
  
-W tym obszernym tutorialu opisaliśmy podstawowe sposoby formułowania zapytań w MySQL na przykładzie bazy sklepu z tabelami klienci, zamowienia i towary. Omówiliśmy pobieranie danych przy pomocy SELECT z klauzulami WHERE, ORDER BY i LIMIT, łączenie tabel za pomocą różnych typów JOIN (INNER, LEFT, RIGHT, FULL) oraz zagnieżdżanie zapytań. Pokazaliśmy także, jak grupować dane używając GROUP BY oraz jak stosować funkcje agregujące takie jak COUNT, SUM i AVG do podsumowywania wyników. Przedstawiliśmy polecenia modyfikujące dane: INSERT (dodawanie nowych rekordów), UPDATE (aktualizacja istniejących) i DELETE (usuwanie rekordów). Zademonstrowaliśmy także przykład podzapytania (SELECT wewnątrz SELECT) oraz stworzenie prostej procedury składowanej.+W tym tutorialu opisaliśmy podstawowe sposoby formułowania zapytań w MySQL na przykładzie bazy sklepu z tabelami klienci, zamowienia i towary. Omówiliśmy pobieranie danych przy pomocy SELECT z klauzulami WHERE, ORDER BY i LIMIT, łączenie tabel za pomocą różnych typów JOIN (INNER, LEFT, RIGHT, FULL) oraz zagnieżdżanie zapytań. Pokazaliśmy także, jak grupować dane używając GROUP BY oraz jak stosować funkcje agregujące takie jak COUNT, SUM i AVG do podsumowywania wyników. Przedstawiliśmy polecenia modyfikujące dane: INSERT (dodawanie nowych rekordów), UPDATE (aktualizacja istniejących) i DELETE (usuwanie rekordów). Zademonstrowaliśmy także przykład podzapytania (SELECT wewnątrz SELECT) oraz stworzenie prostej procedury składowanej.
  
 Dzięki tym przykładowym zapytaniom możesz ćwiczyć pracę z bazą danych i stopniowo rozwijać swoje umiejętności SQL. Pamiętaj, że kluczem jest praktyka – warto eksperymentować na różnych danych i zadaniach, aby lepiej opanować składnię i możliwości MySQL. Dzięki tym przykładowym zapytaniom możesz ćwiczyć pracę z bazą danych i stopniowo rozwijać swoje umiejętności SQL. Pamiętaj, że kluczem jest praktyka – warto eksperymentować na różnych danych i zadaniach, aby lepiej opanować składnię i możliwości MySQL.
 +
 +== Pełen dump bazy danych ==
 +<code mysql>
 +-- Adminer 5.2.1 MySQL 8.0.42 dump
 +
 +SET NAMES utf8;
 +SET time_zone = '+00:00';
 +SET foreign_key_checks = 0;
 +SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
 +
 +DROP DATABASE IF EXISTS `sklep`;
 +CREATE DATABASE `sklep` /*!40100 DEFAULT CHARACTER SET utf8mb3 COLLATE utf8mb3_polish_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;
 +USE `sklep`;
 +
 +DELIMITER ;;
 +
 +CREATE PROCEDURE `LiczbaZamowienDlaKlienta` (IN `client_id` int)
 +BEGIN SELECT COUNT(*) AS liczba_zamowien 
 +FROM zamowienia 
 +WHERE id_klienta = client_id; 
 +END;;
 +
 +DELIMITER ;
 +
 +DROP TABLE IF EXISTS `klienci`;
 +CREATE TABLE `klienci` (
 +  `id_klienta` int NOT NULL,
 +  `imie` varchar(50) COLLATE utf8mb3_polish_ci DEFAULT NULL,
 +  `nazwisko` varchar(50) COLLATE utf8mb3_polish_ci DEFAULT NULL,
 +  `miasto` varchar(50) COLLATE utf8mb3_polish_ci DEFAULT NULL,
 +  `wiek` int DEFAULT NULL,
 +  PRIMARY KEY (`id_klienta`)
 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_polish_ci;
 +
 +INSERT INTO `klienci` (`id_klienta`, `imie`, `nazwisko`, `miasto`, `wiek`) VALUES
 +(1, 'Jan', 'Kowalski', 'Warszawa', 34),
 +(2, 'Anna', 'Nowak', 'Gdańsk', 28),
 +(3, 'Piotr', 'Wiśniewski', 'Poznań', 45),
 +(4, 'Katarzyna', 'Wójcik', 'Gdańsk', 51),
 +(5, 'Michał', 'Kamiński', 'Wrocław', 39),
 +(6, 'Agnieszka', 'Lewandowska', 'Katowice', 23),
 +(7, 'Tomasz', 'Zieliński', 'Warszawa', 62),
 +(8, 'Ewa', 'Szymańska', 'Lublin', 31),
 +(9, 'Adam', 'Dąbrowski', 'Łódź', 27),
 +(11, 'Karolina', 'Mazur', 'Gdynia', 29);
 +
 +DROP TABLE IF EXISTS `towary`;
 +CREATE TABLE `towary` (
 +  `id_towaru` int NOT NULL,
 +  `nazwa` varchar(100) COLLATE utf8mb3_polish_ci DEFAULT NULL,
 +  `kategoria` varchar(50) COLLATE utf8mb3_polish_ci DEFAULT NULL,
 +  `cena` decimal(10,2) DEFAULT NULL,
 +  PRIMARY KEY (`id_towaru`)
 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_polish_ci;
 +
 +INSERT INTO `towary` (`id_towaru`, `nazwa`, `kategoria`, `cena`) VALUES
 +(1, 'Telewizor 55\"', 'Elektronika', 2499.99),
 +(2, 'Laptop', 'Elektronika', 3299.00),
 +(3, 'Smartfon', 'Elektronika', 1999.49),
 +(4, 'Regał na książki', 'Meble', 459.20),
 +(5, 'Krzesło biurowe', 'Meble', 349.00),
 +(6, 'T-shirt męski', 'Odzież', 59.99),
 +(7, 'Sukienka damska', 'Odzież', 129.50),
 +(8, 'Buty sportowe', 'Obuwie', 179.99),
 +(9, 'Słuchawki bezprzewodowe', 'Elektronika', 149.99),
 +(10, 'Książka \"SQL dla początkujących\"', 'Książki', 79.90);
 +
 +DROP TABLE IF EXISTS `zamowienia`;
 +CREATE TABLE `zamowienia` (
 +  `id_zamowienia` int NOT NULL,
 +  `id_klienta` int DEFAULT NULL,
 +  `id_towaru` int DEFAULT NULL,
 +  `ilosc` int DEFAULT NULL,
 +  `DATA` date DEFAULT NULL,
 +  PRIMARY KEY (`id_zamowienia`),
 +  KEY `fk_zamowienia_klienci` (`id_klienta`),
 +  KEY `fk_zamowienia_towary` (`id_towaru`),
 +  CONSTRAINT `fk_zamowienia_klienci` FOREIGN KEY (`id_klienta`) REFERENCES `klienci` (`id_klienta`) ON DELETE CASCADE ON UPDATE CASCADE,
 +  CONSTRAINT `fk_zamowienia_towary` FOREIGN KEY (`id_towaru`) REFERENCES `towary` (`id_towaru`) ON DELETE RESTRICT ON UPDATE CASCADE
 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_polish_ci;
 +
 +INSERT INTO `zamowienia` (`id_zamowienia`, `id_klienta`, `id_towaru`, `ilosc`, `DATA`) VALUES
 +(1, 1, 1, 1, '2024-01-15'),
 +(2, 2, 3, 2, '2024-01-17'),
 +(3, 1, 2, 1, '2024-02-03'),
 +(4, 3, 5, 4, '2024-02-20'),
 +(5, 4, 4, 2, '2024-03-05'),
 +(6, 5, 8, 1, '2024-03-15'),
 +(7, 6, 10, 3, '2024-03-17'),
 +(8, 7, 9, 1, '2024-03-18'),
 +(9, 2, 6, 5, '2024-03-20'),
 +(10, 1, 7, 2, '2024-04-01');
 +
 +-- 2025-05-13 10:05:07 UTC
 +</code>
notatki/bazy_danych.1747129269.txt.gz · ostatnio zmienione: przez administrator