wtorek, 4 października 2016

MySQL via shell PART VI: ALTER TABLE, DELETE, ALL, BOOLEAN & pytania zagnieżdżone


Hejo! 

Tak, kontynuujemy naukę ze strukturalnym językiem zapytań do bazy danych (hoho). Żeby nie przedłużać przejdziemy od razu do konkretów : )

---== TROCHĘ MOŻLIWOŚĆ ALTER TABLE ==---

Okay, najpierw do naszej tabeli w bazie danych 'pracownicy' dodajmy kolejną kolumnę, zaraz po nazwisku pracownika. Na tym etapie nie powinno to stanowić dla nas żadnego problemu, a kod wstawiam tylko gwoli przypomnienia oraz jego utrwalenia w głowie:

alter table pracownicy add dyzur varchar(20) after nazwisko; 

W moim przykładzie ta kolumna już ma miejsce ale mam ochotę wstawić ją sobie ponownie, a co! Co muszę zrobić? Ano usunąć kolumnę dyzur z mojej tabeli pracownicy. Pomoże mi w tym polecnie:

alter table pracownicy drop dyzur; 

o, a teraz bez kozery mogę wstawić ją sobie ponownie powyższą klauzulą ;) 

Dochodzę jednak do wniosku, że chciałbym jednak inaczej nazwać tę kolumnę. Nie trzeba wstawiać nowej (i nie daj Boże wstawiać od nowa wszystkich danych!). Wystarczy proste polecenie zmieniające nazwę kolumny oraz przypisaną do niej zmienną :) 

alter table pracownicy change dyzur mycie_kibli varchar(20);

W klauzuli tej po nazwie tabeli jaką wybieramy używamy polecenia change (z ang. zmiana), a następnie określamy nazwę tabeli, którą chcemy zmienić, nazwę jaką tej tabeli chcemy nadać razem z przypisaną do niej funkcją. Oczywiście funkcje tę możemy rozpisać kodując ją np. w polskich znakach, upewniając się, że MySQL zadba o to, aby każdy rekord w tej kolumnie był wypełniony i nie przybierał wartości zerowej (NULL). Wtedy powyższa klauzula będzie wyglądała w następujący sposób:

alter table pracownicy change dyzur mycie_kibli text character set utf8 collate utf8_polish_ci not null;



Ja akurat swoją klauzulę zakończyłem opcją null, ponieważ nie chciało mi się uzupełniać danych dla tej kolumny. Tak, jestem leniwy. Tak, Ty jesteś leniwy/a bardziej. Zwróć również uwagę proszę, że tą samą klauzulą nie tylko zmieniamy nazwy poszczególnych kolumn ale również same funkcje im przypisane (ja właśnie zrobiłem tak z kolumną 'mycie_kibli').

Podobnie możemy np. odczepić PRIMARY KEY bądź też usuwać AUTO_INCREMENT. Najpierw jednak usuńmy naszą pierwszą kolumnę 'id' w którą wpisane jest zmienna INT, jak i auto inkrementacja oraz primary key. 

alter table pracownicy drop id;

Teraz warto dodać ponownie tę kolumnę, z tym, że chcielibyśmy dodać ją z przodu. Do tego służy komenda FIRST (z ang. pierwszy):

alter table pracownicy add id int primary key auto_increment not null first;

Oczywiście nasz numer identyfikacyjny jest niepowtarzalny, a i jego wartość zawsze musi zawierać się w rekordzie, stąd not null w tej klauzuli :)



Teraz możemy usunąć primary key ale żeby to zrobić musimy najpierw usunąć A_I (tak, dobrze się domysliłeś/aś bystrzaku co oznacza ten skrót):

Zatem, usunąć autoinkrementacje możemy, jak już się pewnie domyślacie poprzez polecenie CHANGE (z ang. zmiana): 

alter table pracownicy change id id int not null;

A następnie usunąć primary_key:

alter table pracownicy drop primary key;

Oczywiście przywrócić można go komendą CHANGE.


A co, jeśli chcielibyśmy zmienić nazwę naszej tabeli? Nic prostszego, używamy wtedy komendy RENAME TO (z ang. przemianuj):

alter table pracownicy rename to niewolnicy;

#heheszki


--=== ZMIENNA BOOLEAN ===--

Zmienna BOOLEAN przechowuje trzy wartości: TRUE (z ang. prawda), FALSE (z ang. fałsz), oraz NULL (brak wartości). 

Chcemy dodać na końcu naszej tabeli kolumnę właśnie z tą zmienną. Powiedzmy, że będzie ona dotyczyć urlopu każdego z pracowników: 

alter table pracownicy add urlop boolean not null; 

Wartość kolumny urlop automatycznie przybierze 0. Teraz chcielibyśmy, aby wszyscy nasi pracownicy pojechali na urlop, ponieważ jesteśmy świetnym szefem (nikt nie mówił, że urlop jednodniowy w ramach ogólnokrajowego protestu to coś złego #heheszki). Warto byłoby zatem ustawić tabelę urlop na wartość TRUE. Zrobimy to prostą, znaną nam dobrze klauzulą UPDATE:

update pracownicy set urlop=1; 

Gwoli ścisłości, tak naprawdę my nie dajemy urlopów. Jak najszybciej chcemy usunąć tę kolumnę z naszej tabeli! Wystarczy wtedy użyć równie prostej klauzuli:

alter table pracownicy drop urlop;



--== USUWANIE POSZCZEGÓLNYCH REKORDÓW ==--

Szczerze to sam jestem zaskoczony faktem, że jeszcze nigdzie nie wspomniałem o klauzuli DELETE FROM (albo wspomniałem ale nie pamiętam :P) ;O

Jak sama nazwa wskazuje delete from (z ang. usuń z) służy do usuwania poszczególnych rekordów czy wartości w kolumnach. Jeżeli np chcielibyśmy usunąć rekord pracownika Jana Nowaka, którego zwolniliśmy z naszej firmy to stosujemy polecenie: 

delete from pracownicy where id=1;

Myślę, że tego akurat tłumaczyć nie muszę :)


--== PYTANIA ZAGNIEŻDŻONE ==-- 

Pytania zagnieżdżone to ciekawa sprawa! : ) Są zapytaniami zawierającymi.. inne zapytania. Popatrz - chcemy wyciągnąć wszystkie dane na temat pracownika, który zarabia ponad średnią wszystkich pracowników. Wtedy można sformułować takie zapytanie:

select * from pracownicy where zarobki>=(select avg(zarobki) from pracownicy);

Sprawa wygląda dosyć prosto - musimy pamiętać, aby drugie zapytanie umieścić w nawiasie! 

A teraz zajmiemy się trudniejszym zadaniem:

Znajdź pracowników z działu 2, którzy zarabiają więcej, niż jakikolwiek pracownik działu 1.

Na logikę rozwiązałbym to w taki sposób:

select zarobki from pracownicy where dzial=1;

a następnie użyłbym zapytania wyszukującego:

select * from pracownicy where dzial=2 and zarobki>x and zarobki>y;

i okay, w tym przypadku uzyskałem informację, którą chciał, kod jednak nie był dynamiczny, a uzyskany wynik otrzymałem wprowadzając dwie komendy, a przy milionowej liczbie rekordów płakałbym gorzkimi łzami. A co, jeśli chciałbym otrzymać odpowiedź za pomocą jednego kodu? Tutaj przychodzi z pomocą operator ALL. Kiedy go używamy? Wtedy, kiedy podczas zapytań zagnieżdżonych zapytania będzie określać jako mniejsze < lub większe >, a same zapytania będą nam zwracać więcej, niż jeden wynik. Stąd przykład z wyciąganiem średniej avg(), ponieważ ona zawsze zwróci nam jeden wynik. Gorzej, kiedy tych wyników dostaniemy więcej, niż jeden. Tutaj trzeba powiedzieć MySQL, że wszystkie wyniki będą brane pod uwagę tak, aby nie zgłupiał otrzymując wiele wyników zwrotnych. Mam nadzieję, że dobrze to wytłumaczyłem.. Postaram się jeszcze przeczytać to jutro na świeżo i poprawić, jeśli trochę zagmatwałem. Pokażę to na przykładzie:

select * from pracownicy where zarobki>all(select zarobki from pracownicy where dzial=1);



Poza ALL istnieje również ANY ale o tym w przyszłej lekcji :) 

Pozdrawiam Was serdecznie  ^_^

F.

PS. Znalazłem świetną bazę do ćwiczeń na serwerze Mirka Zelenta. Podaję Wam do niej link TU

Oczywiście polecam dalszą zabawę z chłopakami z UW-TEAM :) 












Brak komentarzy:

Prześlij komentarz