===== Podstawy =====
=== Operatory logiczne w MySQLu ===
^ Operator logiczny ^ Opis ^
| = | równy |
| != lub <> | różny |
| < | mniejszy |
| > | większy |
| ''<='' | mniejszy lub równy |
| >= | większy lub równy |
Uwaga! "Wartości" NULL nie mogą być porównywane za pomocą operatorów = i !=. Należy tu wykorzystać operatory ''IS NULL'' lub ''NOT NULL''.
Ogólnie:
SELECT [fieldnames]
AS [alias]
FROM [tablename]
WHERE [criteria]
ORDER BY [fieldname to sort on] [DESC]
LIMIT [offset, maxrows]
Uwaga! Nie można używać ''AS'' z ''WHERE''.
=== Pobieranie wartości wybranych pól ===
Pobieranie zawartości pola ''pornid'' z tabeli ''porn'':
SELECT pornid FROM porn;
Pobieranie zawartości kilku pól tabeli ''porn'':
SELECT pornid, pornname FROM porn;
Pobieranie zawartości wszystkich pól tabeli ''porn'':
SELECT * FROM porn;
=== Ograniczanie ilości zwracanych rekordów ===
Pobieranie pierwszych dwóch wierszy, rozpoczynając od rekordu o indeksie 0 pól tabeli ''porn'':
SELECT pornid, pornname FROM porn LIMIT 0, 2;
Gdy nie określimy początkowego rekordu, domyślnie przyjęte będzie 0, a więc:
SELECT pornid, pornname FROM porn LIMIT 2;
zwróci dokładnie to samo co powyższy przykład.
Jeśli interesują nas ''pornid'' i ''pornname'' wydane w Polsce (niezbyt ciekawa lista, wiem) korzystamy z funkcji ''WHERE'':
SELECT pornid, pornname FROM porn WHERE porncountry = 'Poland';
Klauzule ''WHERE'' i ''LIMIT'' można łączyć:
SELECT pornid, pornname FROM porn WHERE porncountry = 'Poland' LIMIT 1;
wyświetli tylko pierwszą polską produkcję. Klauzula ''LIMIT'' zawsze na końcu zapytania!
Warunki można również łączyć za pomocą operatorów logicznych ''AND'' i ''OR''.
SELECT pornnumber, pornid, porncountry FROM porn
WHERE (porncountry = 'Poland'
OR porncountry = 'Ghana')
AND pornnumber < 5;
Nawiasy są niezbędne, bez nich operator ''AND'' zostałby zastosowany wyłącznie do warunku bezpośrednio go poprzedzającego, czyli ''porncountry = 'Ghana'''.
=== Porządkowanie wyników ===
Do sortowania zwracanych wyników używamy klauzuli ''ORDER BY''.
SELECT pornnumber, pornid, porncountry FROM porn
WHERE pornnumber < 5 ORDER BY pornid;
Gdy sortujemy według pól znakowych, MySQL sortuje je według wartości ASCII, więc wielkie litery będą przed małymi. Z tego powodu, wyniki użycia klauzuli ''ORDER BY'' zależeć mogą od zbioru znaków wybranego podczas kompilacji MySQL-a.
Domyślnie ''ORDER BY'' sortuje wartości rosnąco. Aby posortować malejąco, należy skorzystać z kluczowego słowa ''DESC''.
SELECT pornid FROM porn ORDER BY pornid DESC;
Pobrane wiersze można również posortować względem wartości kilku pól.
SELECT pornid, pornname, porncountry FROM porn
WHERE porncontry = 'Poland'
OR porncountry = 'Ghana'
ORDER BY porncountry, pornid DESC;
=== Dopasowywanie wzorców ===
Wykorzystując operatory ''LIKE'' i ''NOT LIKE'' możemy określać wzorce, do których dopasowywane będą łańcuchy znaków.
Znaki specjalne, używane we wzorcach to:
* ''%'' - odpowiada dowolnemu łańcuchowi znaków (coś jak * w DOSie),
* ''_'' - odpowiada dowolnemu znakowi (jak ?).
Jeśli chcemy odszukać wszystkie rekordy, w których wartości pól ''pornwww'' kończą się łańcuchem znaków ''jameson.com'':
SELECT pornid, pornname, porncountry FROM porn
WHERE pornwww LIKE '%jameson.com'
ORDER BY pornname;
Uwaga! Wielkość liter w polach typu ''TEXT'' nie ma znaczenia. Jeżeli potrzebujemy rozróżniać owe, musimy skorzystać z pola typu ''BLOB''.
Przykład poniżej pokazuje wzorzec pasujący do ''pornid'' o wartości ''"sax"'' i do ''"six"'' ale do ''"siux"'' już nie.
SELECT pornid FROM porn WHERE pornid LIKE 's_x';
I na koniec operator ''NOT LIKE'':
SELECT pornid FROM porn
WHERE pornid NOT LIKE 'passion%';
=== Tworzenie podsumowań ===
W MySQL mamy grupę funkcji agregujących, które zamiast zwracania wierszy, podsumowują zawarte w nich informacje:
* ''sum()'' - suma wartości danego pola ze wszystkich zwróconych wierszy,
* ''max()'' i ''min()'' - zwraca odpowiednio największą i najmniejsza wartość z wierszy danego pola,
* ''avg()'' - średnia wartość danego pola,
* ''count()'' - ilość zwróconych wierszy.
Zwracanie najmniejszej i największej wartości pola numerycznego:
SELECT min(pornnumber), max(pornnumber) FROM porn;
Liczbę zwróconych wierszy można określić dwojako:
* ''count(nazwa_pola)'' - zwraca liczbę wierszy, w których określone pole jest różne od ''NULL'',
* ''count(*)'' - zwraca liczbę wszystkich wierszy.
SELECT count(*) FROM porn WHERE porndate < '2009-11-12';
zwróci liczbę porn wydanych przed tą datą.
=== Bardziej złożone zapytania ===
Gdy chcemy wyświetlić listę krajów, w których wyprodukowano kiedykolwiek porn, ale bez powtarzających się wpisów korzystamy ze słowa ''DISTINCT'':
SELECT DISTINCT porncountry FROM porn ORDER BY porncountry;
Jeśli chcemy policzyć ile porn wyprodukowano w każdym kraju piszemy:
SELECT porncountry, count(*) FROM porn
GROUP BY porncountry ORDER BY porncountry DESC;
Klauzula ''GROUP BY'' jest tu niezbędna, bez niej MySQL generuje błąd. Musi ona być na końcu zapytania, ale przed ''ORDER BY'' i ''LIMIT''.
Gdybyśmy chcieli posortować tabelę z naszego ostatniego przykładu względem ilości porn, napotkalibyśmy problem, gdyż w klauzuli ''ORDER BY'' nie możemy odwołać się do funkcji agregującej ''count(*)''. Z pomocą przychodzą nam nazwy umowne (''AS'').
SELECT porncountry, count(*) AS num_porn FROM porn GROUP BY porncountry ORDER BY num_users;
Przypuśćmy, że potrzebujemy listy krajów, w których wyprodukowano więcej niż jeden porn:
SELECT porncountry, count(*) AS num_porn FROM porn
WHERE num_porn > 1 GROUP BY porncountry;
Polecenie to wygeneruje błąd, gdyż nie możemy określić pola ''num_porn'' do momentu określenia sposobu grupowania rekordów (czyli do ''GROUP BY''). Klauzulę ''WHERE'' musimy umieszczać przed ''GROUP BY''. Rozwiązaniem problemu jest zastosowanie klauzuli ''HAVING''. Jej zastosowanie jest takie jak ''WHERE'', lecz umieszczamy ją bezpośrednio za ''GROUP BY'':
SELECT porncountry, count(*) AS num_porn FROM porn
GROUP BY porncountry HAVING num_porn > 1;
=== Pobieranie danych z kilku tabel ===
A co gdybyśmy chcieli pobrać dane z dwóch tabel? No problem:
SELECT porn.pornid, page FROM porn, porn_log
WHERE porn.pornid = porn_log.pornid;
=== Funkcje MySQLa ===
== now() ==
Funkcja zwraca aktualny czas systemowy na komputerze, z serwerem MySQL
mysql> SELECT now();
Output:
+---------------------+
| now() |
+---------------------+
| 2009-11-14 15:58:44 |
+---------------------+
1 row in set (0.00 sec)
== curdate(), curtime() ==
Funkcje zwracają odpowiednio datę i czas
mysql> SELECT curdate(), curtime();
Output:
+------------+-----------+
| curdate() | curtime() |
+------------+-----------+
| 2009-11-14 | 16:04:14 |
+------------+-----------+
1 row in set (0.00 sec)
== substring() ==
Funkcja zwraca daną literę ciągu znaków (pierwsza litera to 1, a nie 0 jak w PHP)
mysql> SELECT substring('test', 1, 1);
Output:
+-------------------------+
| substring('test', 1, 1) |
+-------------------------+
| t |
+-------------------------+
1 row in set (0.00 sec)
== right(), left() ==
Funkcja wyciąga podaną liczbę znaków z prawej strony danej kolumny
mysql> SELECT cust_id, cust_type_cd, city, state, fed_id
-> FROM customer
-> ORDER BY RIGHT(fed_id, 3);
Output:
+---------+--------------+------------+-------+-------------+
| cust_id | cust_type_cd | city | state | fed_id |
+---------+--------------+------------+-------+-------------+
| 1 | I | Lynnfield | MA | 111-11-1111 |
| 10 | B | Salem | NH | 04-1111111 |
| 2 | I | Woburn | MA | 222-22-2222 |
| 11 | B | Wilmington | MA | 04-2222222 |
| 3 | I | Quincy | MA | 333-33-3333 |
| 12 | B | Salem | NH | 04-3333333 |
| 13 | B | Quincy | MA | 04-4444444 |
| 4 | I | Waltham | MA | 444-44-4444 |
| 5 | I | Salem | NH | 555-55-5555 |
| 6 | I | Waltham | MA | 666-66-6666 |
| 7 | I | Wilmington | MA | 777-77-7777 |
| 8 | I | Salem | NH | 888-88-8888 |
| 9 | I | Newton | MA | 999-99-9999 |
+---------+--------------+------------+-------+-------------+
13 rows in set (0.24 sec)
FIXME
===== Inne =====
* [[zadania]]