główna strona
wróć
[MySQL] Łączenie tabel w bazach danych MySQL
Ostatnia zmiana: 16.01.2011, Autor artykułu: Waldemar Miotk
baza.jpg

Dawno już nic nie pisałem o bazach danych. Czas to nadrobić, tym bardziej, że w trakcie mojej pracy programistycznej, często spotykam się z problemem połączenia kilku tabel MySQL-a w jedną. Na tej jednej tabeli, chciałbym wykonywać normalne działania, tak aby uzyskać satysfakcjonujące mnie odpowiedzi. W tym artykule, w skrócie i na przykładach, opiszę stosowanie operatora UNION.

Na początku, zaznaczę jednak, iż niekoniecznie, z punktu widzenia optymalizacji, zapytania tego typu są najlepsze. UNION nie należy do najszybszych działań (też nie najwolniejszych), ale czasami bardzo ułatwiających pracę. Przejdźmy zatem do opisu.

Załóżmy, że w bazie danych mamy trzy tabele :

CREATE TABLE `users1` (
`id` INT( 12 ) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`imie` VARCHAR( 30 ) NOT NULL ,
`nazwisko` VARCHAR( 30 ) NOT NULL ,
`zawod` VARCHAR( 50 ) NOT NULL
) ENGINE = MYISAM ;


CREATE TABLE `users2` (
`id` INT( 12 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`imie` VARCHAR( 30 ) NOT NULL ,
`nazwisko` VARCHAR( 30 ) NOT NULL ,
`miejscowosc` VARCHAR( 50 ) NOT NULL ,
`wiek` VARCHAR( 3 ) NOT NULL
) ENGINE = MYISAM ;


CREATE TABLE `users3` (
`id` INT( 12 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`imie` VARCHAR( 30 ) NOT NULL ,
`nazwisko` VARCHAR( 30 ) NOT NULL ,
`miejscowosc` VARCHAR( 50 ) NOT NULL ,
`wiek` VARCHAR( 3 ) NOT NULL ,
`zawod` VARCHAR( 50 ) NOT NULL
) ENGINE = MYISAM ;


Aby uzyskać prawidłowe złączenie, należy zwrócić uwagę na to, aby w każdej z nich była dokładnie taka sama ilość pól. W takim przypadku jak powyżej połączenie wszystkich trzech tabel możemy uzyskać poprzez zapytanie :

( SELECT imie, nazwisko FROM users1 )
UNION
( SELECT imie, nazwisko FROM users2 )
UNION
( SELECT imie, nazwisko FROM users3 )


Pola `imie` i `nazwisko` są wspólne dla wszystkich tabel, więc tylko te możemy wyświetlić. Możemy jednak korzystać w każdej z tabel z dodatkowych pól do wybierania rekordów, które będą nam potrzebne. Poszukajmy więc fryzjerów z tabeli 1 i 3. W tabeli drugiej brak danych o zawodzie, więc nie możemy tam ich znaleźć.

(SELECT imie,nazwisko FROM users1 WHERE zawod='fryzjer')
UNION
(SELECT imie,nazwisko FROM users3 WHERE zawod='fryzjer')


Dane zostaną dołączone według kolejności dołączania tabel, więc najpierw dane z tabeli 1, potem dane z tabeli 3.

Uzyskane dane możemy sortować, ale jedynie wspólnie. Nie zadziała sortowanie poszczególnych tabel oddzielnie. W końcu jest to już, tak jakby, jedna tabela :

(SELECT imie,nazwisko,zawod FROM users1)
UNION
(SELECT imie,nazwisko,zawod FROM users3)
ORDER BY zawod


W przypadku sortowania wspólnego, trzeba było jednak pole `zawod` umieścić w klauzuli `SELECT`, tak aby było ono dostępne do sortowania poprzez `ORDER BY`. A co w przypadku, gdy szukamy fryzjerów w tabelach 1 i 3 a w tabeli 2 wszystkie osoby są fryzjerami? Chcielibyśmy aby też znajdowały się na naszej liście. Nie trudniejszego, dołączamy tabelę 2 bez warunku :

(SELECT imie,nazwisko FROM users1 WHERE zawod='fryzjer')
UNION
(SELECT imie,nazwisko FROM users2)
UNION
(SELECT imie,nazwisko FROM users3 WHERE zawod='fryzjer')
ORDER BY nazwisko, imie


A co, jeżeli chcielibyśmy wydrukować wszystkich, łącznie z tabelą drugą i ich zawodami? Cóż, w tabeli 2 są sami fryzjerzy, więc pytamy bazę tak :

(SELECT imie,nazwisko,zawod FROM users1)
UNION
(SELECT imie,nazwisko,'fryzjer' as zawod FROM users2)
UNION
(SELECT imie,nazwisko,zawod FROM users3)
ORDER BY zawod, nazwisko, imie


A co jeżeli chcemy wiedzieć, z której tabeli pochodzi dana osoba? Dodajemy dodatkowe pole i wyświetlamy :

(SELECT imie,nazwisko,zawod,'tabela nr 1 - users1' as tabela FROM users1)
UNION
(SELECT imie,nazwisko,'fryzjer' as zawod,'tabela nr 2 - users2' as tabela FROM users2)
UNION
(SELECT imie,nazwisko,zawod,'tabela nr 3 - users3' as tabela FROM users3)
ORDER BY zawod, nazwisko, imie


A teraz, co jeżeli chcielibyśmy się dowiedzieć ilu jest fryzjerów we wszystkich trzech tabelach? Tutaj musimy sięgnąć już do podzapytania : SELECT COUNT(zawod) FROM (

(SELECT imie,nazwisko,zawod,'1' as tabela FROM users1)
UNION
(SELECT imie,nazwisko,'fryzjer' as zawod,'2' as tabela FROM users2)
UNION
(SELECT imie,nazwisko,zawod,'3' as tabela FROM users3)
) as tabele WHERE zawod='fryzjer'


Muszę na zakończenie zaznaczyć, iż tabele na których operuję nie zostały przygotowane, aby budować na nich system produkcyjny. Służą one jedynie dla przykładu. Ostatni przykład to już całkowicie jest kompletnym nieporozumieniem pokazującym jedynie możliwości bazy danych. Tego typu zapytanie, przy większych bazach, będzie generowało ogromne obciążenie serwera, więc lepiej będzie dokonać tego przeliczenia w inny sposób np. wykonując oddzielne zapytania zliczające dla każdej z tabel. Ale jeżeli już się bawimy, to spróbujmy uzyskać odpowiedź na pytanie: ilu przedstawicieli poszczególnych zawodów znajduje się w naszych bazach danych? Oto działanie, które nam na to pytanie odpowie :

SELECT zawod, COUNT(zawod) FROM (
(SELECT imie,nazwisko,zawod,'1' as tabela FROM users1)
UNION
(SELECT imie,nazwisko,'fryzjer' as zawod,'2' as tabela FROM users2)
UNION
(SELECT imie,nazwisko,zawod,'3' as tabela FROM users3)
) as tabele GROUP BY zawod

 

Komentarze(0)

Podpis:
W celu potwierdzenia, zaznacz pole pod znakiem: T
Capcha
(c)2007-2016 Waldemar Miotk - ostatnia aktualizacja silnika 06.02.2016 - Twój IP: 18.97.14.84. Ta strona, aby lepiej działać, używa plików cookie przechowywanych na komputerach użytkowników. Wszystkie prawa do tekstów zamieszczonych na stronie są zastrzeżone, chyba że przy konkretnym tekście znajduje się inna informacja.
go up