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:

  1. Kiedy dodajesz / usuwasz kolumny, nie musisz wprowadzać zmian w miejscu, w którym SELECT *
  2. Krótsze jest pisanie
  3. Widzisz także odpowiedzi, więc czy użycie SELECT * może być kiedykolwiek uzasadnione?

Cons:

  1. 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
  2. Wyjaśnij, jakie dane są używane
  3. Określenie kolumn oznacza błąd podczas usuwania kolumny
  4. Procesor zapytań musi wykonać jeszcze trochę pracy - dowiedzieć się, jakie kolumny istnieją w tabeli (dzięki @vinodadhikary)
  5. Możesz łatwiej znaleźć miejsce, w którym kolumna jest używana
  6. Otrzymasz wszystkie kolumny w złączeniach, jeśli używasz SELECT *
  7. Nie można bezpiecznie używać odwołań porządkowych (chociaż stosowanie odwołań porządkowych do kolumn jest samo w sobie złą praktyką)
  8. 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 do BETWEEN..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 indeksy FULLTEXT nie są używane do wypełniania zapytań przy użyciu LIKE .

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 jak WHERE (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 mikrosekundowym DATETIME(6) .
  • Dba o dni przestępne, koniec roku itp.
  • Jest przyjazny dla indeksu (podobnie BETWEEN ).


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow