Kurs MySQL - pobieranie informacji z tabeli
Pobieranie informacji z tabeli Do pobrania informacji z tabeli używana jest instrukcja SELECT co_wybrać FROM z_której_tabeli WHERE warunki_wyboru ORDER BY kolejność_wierszy;
Wybieranie wszystkich danych z tabeli Najprostsza forma instrukcji mysql> SELECT * FROM zwierze;"); +----------+------------+---------+------+------------+------------+ | imie | wlasciciel | gatunek | plec | urodzony | zmarl | +----------+------------+---------+------+------------+------------+ | Fluffy | Harold | kot | z | 1993-02-04 | NULL | | Claws | Gwen | kot | m | 1994-03-17 | NULL | | Buffy | Harold | pies | z | 1998-05-13 | NULL | | Fang | Benny | pies | m | 1990-08-27 | NULL | | Bowser | Diane | pies | m | 1998-08-31 | 1995-07-29 | | Chirpy | Gwen | ptak | z | 1998-09-11 | NULL | | Whistler | Gwen | ptak | NULL | 1997-12-09 | NULL | | Slim | Benny | ryba | m | 1996-04-29 | NULL | +----------+------------+---------+------+------------+------------+ Ta forma Jest kilka sposobów na poprawę tych danych:
Jak wcześniej widziałeś, łatwo uzyskać dane o całej tabeli. Jednak zazwyczaj nie jest Ci to potrzebne, szczególnie gdy tabela jest sporych rozmiarów. Zamiast tego interesuje Cię odpowiedź na konkretne pytanie, do którego wprowadzasz ograniczenia co do informacji, jakie chcesz otrzymać. Spójrzmy na kilka zapytań, które odpowiadają na pytania związane z Twoimi zwierzętami: Wyświetlanie wybieranych wierszy Możesz wybrać tylko niektóre wiersze ze swojej tabeli. Np. jeżeli chcesz sprawdzić zmianę, jaką wprowadziłeś do daty urodzenia Bowsera, wybierz rekord dotyczący Bowsera w następujący sposób: mysql> SELECT * FROM zwierze WHERE imie = "Bowser" +--------+------------+---------+------+------------+------------+ | imie | wlasciciel | gatunek | plec | urodzony | zmarl | +--------+------------+---------+------+------------+------------+ | Bowser | Diane | pies | m | 1989-08-31 | 1995-07-29 | +--------+------------+---------+------+------------+------------+ Wynik potwierdza, że rok został poprawnie zapisany jako 1989, a nie 1998. Porównywanie łańcuchów znakowych jest niewrażliwe na wielkość liter, więc możesz podać imię jako Możesz zdefiniować warunki dla dowolnej kolumny, nie tylko dla kolumny mysql> SELECT * FROM zwierze WHERE urodzony >= "1998-1-1" +----------+------------+---------+------+------------+-------+ | imie | wlasciciel | gatunek | plec | urodzony | zmarl | +----------+------------+---------+------+------------+-------+ | Chirpy | Gwen | ptak | z | 1998-09-11 | NULL | | Puffball | Diane | gad | z | 1999-03-30 | NULL | +----------+------------+---------+------+------------+-------+ Możesz łączyć warunki, np. dla znalezienia nie psów, ale suk: mysql> SELECT * FROM zwierze WHERE gatunek = "pies" AND plec = "z"; +-------+-------------+---------+------+------------+-------+ | imie | wlasciciel | gatunek | plec | urodzony | zmarl | +-------+-------------+---------+------+------------+-------+ | Buffy | Harold | pies | z | 1989-05-13 | NULL | +-------+-------------+---------+------+------------+-------+ Poprzednie zapytanie wykorzystywało operator logiczny mysql> SELECT * FROM zwierze WHERE gatunek = "ryba" OR gatunek = "ptak"; +----------+------------+---------+------+------------+-------+ | imie | wlasciciel | gatunek | plec | urodzony | zmarl | +----------+------------+---------+------+------------+-------+ | Chirpy | Gwen | ptak | z | 1998-09-11 | NULL | | Whistler | Gwen | ptak | NULL | 1997-12-09 | NULL | | Slim | Benny | ryba | m | 1996-04-29 | NULL | +----------+------------+---------+------+------------+-------+ Operatory mysql> SELECT * FROM zwierze WHERE (gatunek = "kot" AND plec = "m") -> OR (gatunek = "pies" AND plec = "z"); +-------+-------------+---------+------+------------+-------+ | imie | wlasciciel | gatunek | plec | urodzony | zmarl | +-------+-------------+---------+------+------------+-------+ | Claws | Gwen | kot | m | 1994-03-17 | NULL | | Buffy | Harold | pies | z | 1989-05-13 | NULL | +-------+-------------+---------+------+------------+-------+ Wyświetlanie wybieranych kolumn Jeżeli nie chcesz oglądać całego wiersza z tabeli, po prostu podaj nazwy tych kolumn, które Cię interesują oddzielając je
przecinkami. Np. jeżeli chcesz wiedzieć kiedy urodziło się każde z Twoich zwierząt, wybierz kolumny mysql> SELECT imie, urodzony FROM zwierze; +----------+------------+ | imie | urodzony | +----------+------------+ | Fluffy | 1993-02-04 | | Claws | 1994-03-17 | | Buffy | 1989-05-13 | | Fang | 1990-08-27 | | Bowser | 1989-08-31 | | Chirpy | 1998-09-11 | | Whistler | 1997-12-09 | | Slim | 1996-04-29 | | Puffball | 1999-03-30 | +----------+------------+ Aby poznać wszystkich właścicieli zwierząt, użyj następującego zapytania: mysql> SELECT wlasciciel FROM zwierze; +------------+ | wlasciciel | +------------+ | Harold | | Gwen | | Harold | | Benny | | Diane | | Gwen | | Gwen | | Benny | +------------+ Jednak, zauważ że powyższe zapytanie pobiera po prostu wartość pola mysql> SELECT DISTINCT wlasciciel FROM zwierze; +------------+ | wlasciciel | +------------+ | Harold | | Gwen | | Benny | | Diane | +------------+ Możesz też użyć klauzuli mysql> SELECT imie, gatunek, urodzony FROM zwierze -> WHERE gatunek = "pies" OR gatunek = "kot"; +--------+---------+------------+ | imie | gatunek | urodzony | +--------+---------+------------+ | Fluffy | kot | 1993-02-04 | | Claws | kot | 1994-03-17 | | Buffy | pies | 1989-05-13 | | Fang | pies | 1990-08-27 | | Bowser | pies | 1998-08-31 | +--------+---------+------------+ Sortowanie wierszy Być może zauważyłeś w poprzednim przykładzie, że wierszy wyniku wyświetlane są bez jakiegokolwiek porządku. Jednak, często łatwiej
jest analizować dane, gdy wiersze są posortowane według jakiegoś klucza. Aby posortować rezultat zapytania, użyj klauzuli
Poniżej przedstawione są posortowane daty urodzenia zwierząt: mysql> SELECT imie, urodzony FROM zwierze ORDER BY urodzony; +----------+------------+ | imie | urodzony | +----------+------------+ | Buffy | 1989-05-13 | | Fang | 1990-08-27 | | Fluffy | 1993-02-04 | | Claws | 1994-03-17 | | Slim | 1996-04-29 | | Whistler | 1997-12-09 | | Bowser | 1998-08-31 | | Chirpy | 1998-09-11 | +----------+------------+ Aby sortować w porządku odwrotnym, dodaj słowo kluczowe mysql> SELECT imie, urodzony FROM zwierze ORDER BY urodzony DESC; +----------+------------+ | imie | urodzony | +----------+------------+ | Chirpy | 1998-09-11 | | Bowser | 1998-08-31 | | Whistler | 1997-12-09 | | Slim | 1996-04-29 | | Claws | 1994-03-17 | | Fluffy | 1993-02-04 | | Fang | 1990-08-27 | | Buffy | 1989-05-13 | +----------+------------+ Możesz również sortować wiersze według kilku kolumnach. Np. aby uporządkować wynik według rodzaju zwierzęcia, a następnie według daty urodzenia z najmłodszymi pokazanymi najpierw, użyj zapytania: mysql> SELECT imie, gatunek, urodzony FROM zwierze ORDER BY gatunek, urodzony DESC; +----------+---------+------------+ | imie | gatunek | urodzony | +----------+---------+------------+ | Claws | kot | 1994-03-17 | | Fluffy | kot | 1993-02-04 | | Bowser | pies | 1998-08-31 | | Fang | pies | 1990-08-27 | | Buffy | pies | 1989-05-13 | | Chirpy | ptak | 1998-09-11 | | Whistler | ptak | 1997-12-09 | | Slim | ryba | 1996-04-29 | +----------+---------+------------+ Zauważ, że słowo kluczowe Obliczanie dat MySQL dostarcza wielu funkcji, których możesz użyć do wykonywania operacji na datach, na przykład do obliczenia wieku lub wyciągnięcia części dat. Aby określić ile lat ma każde zwierzę, musisz obliczyć wiek jako różnicę między datą jego urodzenia a datą aktualną. Robi się to poprzez zamianę obu dat na ilość dni, obliczenie różnicy i podzielenie przez 365: mysql> SELECT imie, (TO_DAYS(NOW())-TO_DAYS(urodzony))/365 FROM zwierze; +----------+----------------------------------------+ | imie | (TO_DAYS(NOW())-TO_DAYS(urodzony))/365 | +----------+----------------------------------------+ | Fluffy | 12.32 | | Claws | 11.21 | | Buffy | 16.05 | | Fang | 14.76 | | Bowser | 6.75 | | Chirpy | 6.72 | | Whistler | 7.47 | | Slim | 9.09 | +----------+----------------------------------------+ To działa, jednak kilka rzeczy można udoskonalić. Po pierwsze, wynik byłby czytelniejszy, gdyby wiersze przedstawione były w jakimś porządku. Po drugie, nagłówek dla kolumny zawierającej wiek nie mówi zbyt wiele. Pierwszy problem można rozwiązać przez dodanie klauzuli mysql> SELECT imie, (TO_DAYS(NOW())-TO_DAYS(urodzony))/365 AS wiek -> FROM zwierze ORDER BY imie; +----------+-------+ | imie | wiek | +----------+-------+ | Bowser | 6.75 | | Buffy | 16.05 | | Chirpy | 6.72 | | Claws | 11.21 | | Fang | 14.76 | | Fluffy | 12.32 | | Slim | 9.09 | | Whistler | 7.47 | +----------+-------+ Aby posortować według mysql> SELECT imie, (TO_DAYS(NOW())-TO_DAYS(urodzony))/365 AS wiek -> FROM zwierze ORDER BY wiek; +----------+-------+ | imie | wiek | +----------+-------+ | Chirpy | 6.72 | | Bowser | 6.75 | | Whistler | 7.47 | | Slim | 9.09 | | Claws | 11.21 | | Fluffy | 12.32 | | Fang | 14.76 | | Buffy | 16.05 | +----------+-------+ Można użyć podobnego zapytania aby określić wiek, w którym zmarło dane zwierzę. To, które z nich zmarło określasz z kolei przez
sprawdzenie, czy wartość kolumny mysql> SELECT imie, urodzony, zmarl, -> (TO_DAYS(zmarl) - TO_DAYS(urodzony)) / 365 AS wiek -> FROM zwierze WHERE zmarl IS NOT NULL ORDER BY wiek; +--------+------------+------------+------+ | imie | urodzony | zmarl | wiek | +--------+------------+------------+------+ | Bowser | 1989-08-31 | 1995-07-29 | 5.91 | +--------+------------+------------+------+ Zapytanie to używa zapisu A co, jeżeli chcesz wiedzieć, które z Twoich zwierząt ma w przyszłym miesiącu urodziny? Dla tego typu operacji, rok i dzień
są nieistotne, chcesz po prostu wydobyć część opisującą miesiąc z kolumny mysql> SELECT imie, urodzony, MONTH(urodzony) FROM zwierze; +----------+------------+-----------------+ | imie | urodzony | MONTH(urodzony) | +----------+------------+-----------------+ | Fluffy | 1993-02-04 | 2 | | Claws | 1994-03-17 | 3 | | Buffy | 1989-05-13 | 5 | | Fang | 1990-08-27 | 8 | | Bowser | 1989-08-31 | 8 | | Chirpy | 1998-09-11 | 9 | | Whistler | 1997-12-09 | 12 | | Slim | 1996-04-29 | 4 | | Puffball | 1999-03-30 | 3 | +----------+------------+-----------------+ Proste jest też znajdowanie zwierząt, które mają urodziny w nadchodzącym miesiącu. Przypuśćmy, że mamy kwiecień.
Wartość miesiąca w dacie wynosi więc mysql> SELECT imie, urodzony FROM zwierze WHERE MONTH(urodzony) = 5; +-------+------------+ | imie | urodzony | +-------+------------+ | Buffy | 1989-05-13 | +-------+------------+ Jest tu jednak mała komplikacja jeżeli mamy właśnie grudzień. Nie możesz tak sobie po prostu dodać jeden do numeru miesiąca
( Możesz jednak napisać to zapytanie tak, że będzie działać bez względu na bieżący miesiąc. Nie będziesz musiał nawet używać
konkretnej wartości miesiąca w zapytaniu. Funkcja mysql> SELECT imie, urodzony FROM zwierze -> WHERE MONTH(urodzony) = MONTH(DATE_ADD(NOW(), INTERVAL 1 MONTH)); Innym sposobem wykonania tego zadania jest dodanie mysql> SELECT imie, urodzony FROM zwierze -> WHERE MONTH(urodzony) = MOD(MONTH(NOW()), 12) + 1; Zauważ, że Używanie wartości Wartość mysql> SELECT 1 = NULL, 1 != NULL, 1 < NULL, 1 > NULL;"; +----------+-----------+----------+----------+ | 1 = NULL | 1 != NULL | 1 < NULL | 1 > NULL | +----------+-----------+----------+----------+ | NULL | NULL | NULL | NULL | +----------+-----------+----------+----------+ Jak wyraźnie widać, nie otrzymujemy żadnych sensownych wyników tych porównań. Zamiast tego użyj operatorów mysql> SELECT 1 IS NULL, 1 IS NOT NULL; +-----------+---------------+ | 1 IS NULL | 1 IS NOT NULL | +-----------+---------------+ | 0 | 1 | +-----------+---------------+ W MySQL 0 oznacza fałsz, a 1 prawdę. Właśnie to wyjątkowe traktowanie wartości Dopasowywanie do wzorca (LIKE) Dopasowywanie do wzorca pozwala na używanie znaku '_' do dopasowania dowolnego pojedynczego znaku oraz
'%' do dopasowania dowolnej ilości znaków (również 0). W MySQL wzorce są domyślnie niewrażliwe na wielkość
znaków. Kilka przykładów znajdziesz poniżej. Zauważ, że nie możesz użyć Aby znaleźć imiona zaczynające się na 'b': mysql> SELECT * FROM zwierze WHERE imie LIKE "b%"; +--------+-------------+---------+------+------------+------------+ | imie | wlasciciel | gatunek | plec | urodzony | zmarl | +--------+-------------+---------+------+------------+------------+ | Buffy | Harold | pies | z | 1989-05-13 | NULL | | Bowser | Diane | pies | m | 1989-08-31 | 1995-07-29 | +--------+-------------+---------+------+------------+------------+ Aby znaleźć imiona kończące się 'fy': mysql> SELECT * FROM zwierze WHERE imie LIKE "%fy"; +--------+-------------+---------+------+------------+-------+ | imie | wlasciciel | gatunek | plec | urodzony | zmarl | +--------+-------------+---------+------+------------+-------+ | Fluffy | Harold | kot | z | 1993-02-04 | NULL | | Buffy | Harold | pies | z | 1989-05-13 | NULL | +--------+-------------+---------+------+------------+-------+ Aby znaleźć imiona zawierające 'w': mysql> SELECT * FROM zwierze WHERE imie LIKE "%w%"; +----------+-------------+---------+------+------------+------------+ | imie | wlasciciel | gatunek | plec | urodzony | zmarl | +----------+-------------+---------+------+------------+------------+ | Claws | Gwen | kot | m | 1994-03-17 | NULL | | Bowser | Diane | pies | m | 1989-08-31 | 1995-07-29 | | Whistler | Gwen | ptak | NULL | 1997-12-09 | NULL | +----------+-------------+---------+------+------------+------------+ Aby znaleźć imiona zawierające dokładnie pięć znaków użyj '_': mysql> SELECT * FROM zwierze WHERE imie LIKE "_____"; +--------+-------------+---------+------+------------+-------+ | imie | wlasciciel | gatunek | plec | urodzony | zmarl | +--------+-------------+---------+------+------------+-------+ | Claws | Gwen | kot | m | 1994-03-17 | NULL | | Buffy | Harold | pies | z | 1989-05-13 | NULL | +--------+-------------+---------+------+------------+-------+ Inny typ dopasowywania wzorców obsługiwanych przez MySQL wykorzystuje rozszerzone wyrażenia regularne. Kiedy testujesz
dopasowanie tego typu użyj operatorów Znakami charakterystycznymi dla wyrażeń regularnych są:
Aby pokazać jak działają wyrażenia regularne, zapytania używające W celu znalezienia imienia zaczynającego się od 'b', użyj '^', aby dopasować wzorzec do początku imienia oraz '[bB]' aby dopasować małe lub wielkie 'b': mysql> SELECT * FROM zwierze WHERE imie REGEXP "^[bB]"; Aby znaleźć imiona kończące się 'fy', użyj '$' do dopasownia do końca imienia: mysql> SELECT * FROM zwierze WHERE imie REGEXP "fy$"; Aby znaleźć imiona zawierające 'w', użyj '[wW]' do odpasowania małego lub wielkiego 'w': mysql> SELECT * FROM zwierze WHERE imie REGEXP "[wW]"; echo $hi->parse_code(); Ponieważ w przypadku wyrażeń regularnych wzorzec zostaje dopasowany, jeżeli wystąpi gdziekolwiek w testowanej wartości, to nie jest konieczne stosowanie w poprzednich zapytaniach maski po którejkolwiek ze stron wzorca, aby dopasować wzorzec do całej wartości tak jak to było w przypadku wzorców LIKE. Aby znaleźć imiona zawierające dokładnie pięć znaków, użyj '^' i '$', aby dopasować początek i koniec oraz pięć wystąpień '.' pomiędzy nimi: mysql> SELECT * FROM zwierze WHERE imie REGEXP "^.....$"; Mozesz także użyć operatora '{n}' co oznacza "powtórz- mysql> SELECT * FROM zwierze WHERE imie REGEXP "^.{5}$"; Zliczanie rekordów tabeli Bazy danych często są używane do odpowiedzi na pytanie "Jak często pewien typ/wartość występuje w tabeli?". Np.: jeżeli chcesz wiedzieć ile masz zwierząt, ile ma zwierząt każdy z właścicieli lub chciałbyś dokonać spisu swoich zwierząt. Zliczenie całkowitej liczby zwierząt jest po prostu pytaniem "Ile wierszy występuje w tabeli mysql> SELECT COUNT(*) FROM zwierze; +----------+ | COUNT(*) | +----------+ | 9 | +----------+ Jak pamiętasz, wcześniej wysyłaliśmy zapytanie o imiona właścicieli zwierzęta. Możesz teraz użyć mysql> SELECT wlasciciel, COUNT(*) FROM zwierze GROUP BY wlasciciel; +------------+----------+ | wlasciciel | COUNT(*) | +------------+----------+ | Benny | 2 | | Diane | 2 | | Gwen | 3 | | Harold | 2 | +------------+----------+ Zauważ użycie mysql> SELECT wlasciciel, COUNT(wlasciciel) FROM zwierze; ERROR 1140 at line 1: Mixing of GROUP columns (MIN(),MAX(),COUNT()...) with no GROUP columns is illegal if there is no GROUP BY clause
Liczba zwierząt każdego gatunku: mysql> SELECT gatunek, COUNT(*) FROM zwierze GROUP BY gatunek; +---------+----------+ | gatunek | COUNT(*) | +---------+----------+ | ptak | 2 | | kot | 2 | | pies | 3 | | gad | 1 | | ryba | 1 | +---------+----------+ Liczba zwierząt wg płci: mysql> SELECT plec, COUNT(*) FROM zwierze GROUP BY plec; +------+----------+ | plec | COUNT(*) | +------+----------+ | NULL | 1 | | z | 4 | | m | 4 | +------+----------+ (W powyższym wyniku wartość Liczba zwierząt w kombinacji gatunku i płci: mysql> SELECT gatunek, plec, COUNT(*) FROM zwierze GROUP BY gatunek, plec; +---------+------+----------+ | gatunek | plec | COUNT(*) | +---------+------+----------+ | ptak | NULL | 1 | | ptak | z | 1 | | kot | z | 1 | | kot | m | 1 | | pies | z | 1 | | pies | m | 2 | | gad | z | 1 | | ryba | m | 1 | +---------+------+----------+ Używając mysql> SELECT gatunek, plec, COUNT(*) FROM zwierze -> WHERE gatunek = "pies" OR gatunek = "kot" -> GROUP BY gatunek, plec; +---------+------+----------+ | gatunek | plec | COUNT(*) | +---------+------+----------+ | kot | z | 1 | | kot | m | 1 | | pies | z | 1 | | pies | m | 2 | +---------+------+----------+ Lub gdybyś chciałbyś otrzymać ilość zwierząt według płci, ale tylko tych, dla których płeć jest znana: mysql> SELECT gatunek, plec, COUNT(*) FROM zwierze -> WHERE plec IS NOT NULL -> GROUP BY gatunek, plec; +---------+------+----------+ | gatunek | plec | COUNT(*) | +---------+------+----------+ | ptak | z | 1 | | kot | z | 1 | | kot | m | 1 | | pies | z | 1 | | pies | m | 2 | | gad | z | 1 | | ryba | m | 1 | +---------+------+----------+
|