MySQL
WYBIERZ
Szukaj…
Wprowadzenie
SELECT
służy do pobierania wierszy wybranych z jednej lub więcej tabel.
Składnia
SELECT DISTINCT [wyrażenia] FROM TableName [GDZIE warunki]; /// Prosty wybór
SELECT DISTINCT (a), b ... jest taki sam jak SELECT DISTINCT a, b ...
WYBIERZ [WSZYSTKO | WYRÓŻNIJ | DISTINCTROW] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT | SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] wyrażenia z tabel [GDZIE warunki] [GRUPUJĄCE według wyrażeń] [WARUNEK POSZUKIWANIA] [ZAMÓWIENIE BY wyrażenie [ASC | DESC]] [LIMIT [wartość_przesunięcia] liczba_wierszy | LIMIT liczba_przycinanie PRZESUNIĘCIE wartość_wyrównania] [PROCEDURA nazwa_procedury] [INTO [Opcje WYJŚCIA „nazwa_pliku” | DUMPFILE „nazwa_pliku” | @ zmienna1, @ zmienna2, ... @variable_n] [DO AKTUALIZACJI | LOCK IN SHARE MODE]; /// Pełna wybierz składnię
Uwagi
Aby uzyskać więcej informacji na temat instrukcji SELECT
MySQL , zapoznaj się z Dokumentami MySQL .
Wybierz według nazwy kolumny
CREATE TABLE stack(
id INT,
username VARCHAR(30) NOT NULL,
password VARCHAR(30) NOT NULL
);
INSERT INTO stack (`id`, `username`, `password`) VALUES (1, 'Foo', 'hiddenGem');
INSERT INTO stack (`id`, `username`, `password`) VALUES (2, 'Baa', 'verySecret');
Pytanie
SELECT id FROM stack;
Wynik
+------+
| id |
+------+
| 1 |
| 2 |
+------+
Wybierz wszystkie kolumny (*)
Pytanie
SELECT * FROM stack;
Wynik
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 1 | admin | admin |
| 2 | stack | stack |
+------+----------+----------+
2 rows in set (0.00 sec)
Możesz wybrać wszystkie kolumny z jednej tabeli w złączeniu, wykonując:
SELECT stack.* FROM stack JOIN Overflow ON stack.id = Overflow.id;
Najlepsza praktyka Nie używaj *
chyba że debugujesz lub pobierasz wiersze do tablic asocjacyjnych, w przeciwnym razie zmiany schematu (ADD / DROP / zmiana kolejności kolumn) mogą prowadzić do nieprzyjemnych błędów aplikacji. Ponadto, jeśli podasz listę kolumn, których potrzebujesz w zestawie wyników, narzędzie do planowania zapytań MySQL często może zoptymalizować zapytanie.
Plusy:
- Kiedy dodajesz / usuwasz kolumny, nie musisz wprowadzać zmian w miejscu, w którym
SELECT *
- Krótsze jest pisanie
- Widzisz także odpowiedzi, więc czy użycie
SELECT *
może być kiedykolwiek uzasadnione?
Cons:
- Zwracasz więcej danych, niż potrzebujesz. Załóżmy, że dodajesz kolumnę VARBINARY, która zawiera 200 tys. Na wiersz. Potrzebujesz tylko tych danych w jednym miejscu dla jednego rekordu - używając
SELECT *
możesz zwrócić 2 MB na 10 wierszy, których nie potrzebujesz - Wyjaśnij, jakie dane są używane
- Określenie kolumn oznacza błąd podczas usuwania kolumny
- Procesor zapytań musi wykonać jeszcze trochę pracy - dowiedzieć się, jakie kolumny istnieją w tabeli (dzięki @vinodadhikary)
- Możesz łatwiej znaleźć miejsce, w którym kolumna jest używana
- Otrzymasz wszystkie kolumny w złączeniach, jeśli używasz SELECT *
- Nie można bezpiecznie używać odwołań porządkowych (chociaż stosowanie odwołań porządkowych do kolumn jest samo w sobie złą praktyką)
- W złożonych zapytaniach z polami
TEXT
zapytanie może zostać spowolnione przez mniej optymalne przetwarzanie tabeli temp
WYBIERZ za pomocą GDZIE
Pytanie
SELECT * FROM stack WHERE username = "admin" AND password = "admin";
Wynik
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 1 | admin | admin |
+------+----------+----------+
1 row in set (0.00 sec)
Zapytanie z zagnieżdżonym WYBOREM w klauzuli WHERE
Klauzula WHERE
może zawierać dowolną prawidłową instrukcję SELECT
do pisania bardziej złożonych zapytań. To jest zapytanie „zagnieżdżone”
Pytanie
Zapytania zagnieżdżone są zwykle używane do zwracania pojedynczych wartości atomowych z zapytań do porównań.
SELECT title FROM books WHERE author_id = (SELECT id FROM authors WHERE last_name = 'Bar' AND first_name = 'Foo');
Wybiera wszystkie nazwy użytkowników bez adresu e-mail
SELECT * FROM stack WHERE username IN (SELECT username FROM signups WHERE email IS NULL);
Oświadczenie: Rozważ użycie sprzężeń w celu poprawy wydajności podczas porównywania całego zestawu wyników.
WYBIERZ za pomocą LIKE (%)
CREATE TABLE stack
( id int AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(100) NOT NULL
);
INSERT stack(username) VALUES
('admin'),('k admin'),('adm'),('a adm b'),('b XadmY c'), ('adm now'), ('not here');
„adm” gdziekolwiek:
SELECT * FROM stack WHERE username LIKE "%adm%";
+----+-----------+
| id | username |
+----+-----------+
| 1 | admin |
| 2 | k admin |
| 3 | adm |
| 4 | a adm b |
| 5 | b XadmY c |
| 6 | adm now |
+----+-----------+
Zaczyna się od „adm”:
SELECT * FROM stack WHERE username LIKE "adm%";
+----+----------+
| id | username |
+----+----------+
| 1 | admin |
| 3 | adm |
| 6 | adm now |
+----+----------+
Kończy się na „adm”:
SELECT * FROM stack WHERE username LIKE "%adm";
+----+----------+
| id | username |
+----+----------+
| 3 | adm |
+----+----------+
Tak jak znak %
w klauzuli LIKE
pasuje do dowolnej liczby znaków, znak _
pasuje tylko do jednego znaku. Na przykład,
SELECT * FROM stack WHERE username LIKE "adm_n";
+----+----------+
| id | username |
+----+----------+
| 1 | admin |
+----+----------+
Uwagi dotyczące wydajności Jeśli indeks username
zawiera indeks, to
-
LIKE 'adm'
wykonuje to samo co `= 'adm' -
LIKE 'adm%
jest „zakresem”, podobnym doBETWEEN..AND..
Może dobrze wykorzystać indeks na kolumnie. -
LIKE '%adm'
(lub jakikolwiek wariant z wiodącym znakiem wieloznacznym) nie może używać żadnego indeksu. Dlatego będzie wolno. W tabelach z wieloma wierszami może być tak powolny, że jest bezużyteczny. -
RLIKE
(REGEXP
) jest zwykle wolniejszy niżLIKE
, ale ma więcej możliwości. - Podczas gdy MySQL oferuje indeksowanie
FULLTEXT
dla wielu typów tabel i kolumn, te indeksyFULLTEXT
nie są używane do wypełniania zapytań przy użyciuLIKE
.
WYBIERZ za pomocą Alias (AS)
Aliasy SQL służą do tymczasowej zmiany nazwy tabeli lub kolumny. Są one ogólnie stosowane w celu poprawy czytelności.
Pytanie
SELECT username AS val FROM stack;
SELECT username val FROM stack;
(Uwaga: AS
jest składniowo opcjonalny).
Wynik
+-------+
| val |
+-------+
| admin |
| stack |
+-------+
2 rows in set (0.00 sec)
WYBIERZ z klauzulą LIMIT
Pytanie:
SELECT *
FROM Customers
ORDER BY CustomerID
LIMIT 3;
Wynik:
Identyfikator klienta | CustomerName | Nazwa Kontaktu | Adres | Miasto | Kod pocztowy | Kraj |
---|---|---|---|---|---|---|
1 | Alfreds Futterkiste | Maria Anders | Obere Str. 57 | Berlin | 12209 | Niemcy |
2) | Ana Trujillo Emparedados i helados | Ana Trujillo | Avda. de la Constitución 2222 | México DF | 05021 | Meksyk |
3) | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México DF | 05023 | Meksyk |
Najlepsze praktyki Zawsze używaj ORDER BY
gdy używasz LIMIT
; w przeciwnym razie rzędy, które otrzymasz, będą nieprzewidywalne.
Pytanie:
SELECT *
FROM Customers
ORDER BY CustomerID
LIMIT 2,1;
Wyjaśnienie:
Gdy klauzula LIMIT
zawiera dwie liczby, jest interpretowana jako LIMIT offset,count
. W tym przykładzie zapytanie pomija dwa rekordy i zwraca jeden.
Wynik:
Identyfikator klienta | CustomerName | Nazwa Kontaktu | Adres | Miasto | Kod pocztowy | Kraj |
---|---|---|---|---|---|---|
3) | Antonio Moreno Taquería | Antonio Moreno | Mataderos 2312 | México DF | 05023 | Meksyk |
Uwaga:
Wartości w klauzulach LIMIT
muszą być stałymi; nie mogą to być wartości kolumn.
WYBIERZ za pomocą DISTINCT
Klauzula DISTINCT
po SELECT
eliminuje duplikaty wierszy ze zbioru wyników.
CREATE TABLE `car`
( `car_id` INT UNSIGNED NOT NULL PRIMARY KEY,
`name` VARCHAR(20),
`price` DECIMAL(8,2)
);
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (1, 'Audi A1', '20000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (2, 'Audi A1', '15000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (3, 'Audi A2', '40000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (4, 'Audi A2', '40000');
SELECT DISTINCT `name`, `price` FROM CAR;
+---------+----------+
| name | price |
+---------+----------+
| Audi A1 | 20000.00 |
| Audi A1 | 15000.00 |
| Audi A2 | 40000.00 |
+---------+----------+
DISTINCT
działa we wszystkich kolumnach, aby dostarczać wyniki, a nie poszczególne kolumny. To ostatnie jest często błędnym przekonaniem nowych programistów SQL. Krótko mówiąc, liczy się odrębność na poziomie wierszy zestawu wyników, a nie odrębność na poziomie kolumny. Aby to zwizualizować, spójrz na „Audi A1” w powyższym zestawie wyników.
W przypadku późniejszych wersji MySQL, DISTINCT
ma wpływ na jego użycie obok ORDER BY
. ONLY_FULL_GROUP_BY
ustawienie ONLY_FULL_GROUP_BY
jak widać na poniższej stronie podręcznika MySQL zatytułowanej Obsługa MySQL dla GROUP BY .
WYBIERZ za pomocą LIKE (_)
Znak _
we wzorze klauzuli LIKE
pasuje do pojedynczego znaku.
Pytanie
SELECT username FROM users WHERE users LIKE 'admin_';
Wynik
+----------+
| username |
+----------+
| admin1 |
| admin2 |
| admin- |
| adminA |
+----------+
Wybierz za pomocą CASE lub IF
Pytanie
SELECT st.name,
st.percentage,
CASE WHEN st.percentage >= 35 THEN 'Pass' ELSE 'Fail' END AS `Remark`
FROM student AS st ;
Wynik
+--------------------------------+
| name | percentage | Remark |
+--------------------------------+
| Isha | 67 | Pass |
| Rucha | 28 | Fail |
| Het | 35 | Pass |
| Ansh | 92 | Pass |
+--------------------------------+
Lub z IF
SELECT st.name,
st.percentage,
IF(st.percentage >= 35, 'Pass', 'Fail') AS `Remark`
FROM student AS st ;
NB
IF(st.percentage >= 35, 'Pass', 'Fail')
Oznacza to: JEŻELI procent st.> = 35 jest PRAWDA, to zwróć
'Pass'
ELSE return'Fail'
WYBIERZ za pomocą MIĘDZY
Możesz użyć klauzuli BETWEEN, aby zastąpić kombinację warunków „większy niż równy ORAZ mniejszy niż równy”.
Dane
+----+-----------+
| id | username |
+----+-----------+
| 1 | admin |
| 2 | root |
| 3 | toor |
| 4 | mysql |
| 5 | thanks |
| 6 | java |
+----+-----------+
Zapytanie z operatorami
SELECT * FROM stack WHERE id >= 2 and id <= 5;
Podobne zapytanie z BETWEEN
SELECT * FROM stack WHERE id BETWEEN 2 and 5;
Wynik
+----+-----------+
| id | username |
+----+-----------+
| 2 | root |
| 3 | toor |
| 4 | mysql |
| 5 | thanks |
+----+-----------+
4 rows in set (0.00 sec)
Uwaga
MIĘDZY używa
>=
i<=
, nie>
i<
.
Używanie NIE MIĘDZY
Jeśli chcesz użyć negatywu, możesz użyć NOT
. Na przykład :
SELECT * FROM stack WHERE id NOT BETWEEN 2 and 5;
Wynik
+----+-----------+
| id | username |
+----+-----------+
| 1 | admin |
| 6 | java |
+----+-----------+
2 rows in set (0.00 sec)
Uwaga
NIE MIĘDZY używa
>
i<
>=
i<=
To znaczy,WHERE id NOT BETWEEN 2 and 5
jest taki sam jakWHERE (id < 2 OR id > 5)
.
Jeśli masz indeks w kolumnie używanej podczas wyszukiwania BETWEEN
, MySQL może używać tego indeksu do skanowania zakresu.
Wybierz z zakresem dat
SELECT ... WHERE dt >= '2017-02-01'
AND dt < '2017-02-01' + INTERVAL 1 MONTH
Jasne, można to zrobić BETWEEN
i włączenia 23:59:59
. Ale wzór ma następujące zalety:
- Nie masz wstępnie obliczonej daty końcowej (która często jest dokładna od początku)
- Nie dołączasz obu punktów końcowych (jak
BETWEEN
), ani nie wpisujesz „23: 59: 59”, aby tego uniknąć. - Działa z
DATE
,TIMESTAMP
,DATETIME
, a nawet z mikrosekundowymDATETIME(6)
. - Dba o dni przestępne, koniec roku itp.
- Jest przyjazny dla indeksu (podobnie
BETWEEN
).