Поиск…


Вступление

SELECT используется для извлечения строк, выбранных из одной или нескольких таблиц.

Синтаксис

  • SELECT DISTINCT [выражения] FROM TableName [условия WHERE]; /// Простой выбор

  • SELECT DISTINCT (a), b ... совпадает с SELECT DISTINCT a, b ...

  • SELECT [ALL | DISTINCT | DISTINCTROW] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT | SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] выражения из таблиц [условия WHERE] [выражения GROUP BY] [условие HAVING] [выражение ORDER BY [ASC | DESC]] [LIMIT [offset_value] number_rows | LIMIT number_rows OFFSET offset_value] [PROCEDURE имя_процесса] [INTO [OUTFILE 'имя_файла' параметры | DUMPFILE 'имя_файла' | @ variable1, @ variable2, ... @variable_n] [FOR UPDATE | LOCK IN SHARE MODE]; /// Полный синтаксис выбора

замечания

Для получения дополнительной информации о SELECT MySQL обратитесь к Документам MySQL .

SELECT по имени столбца

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');

запрос

SELECT id FROM stack;

Результат

+------+
| id   |
+------+
|    1 |
|    2 |
+------+

ВЫБЕРИТЕ все столбцы (*)

запрос

SELECT * FROM stack;

Результат

+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
|    2 | stack    | stack    |
+------+----------+----------+
2 rows in set (0.00 sec)

Вы можете выбрать все столбцы из одной таблицы в соединении, выполнив:

SELECT stack.* FROM stack JOIN Overflow ON stack.id = Overflow.id;

Лучшая практика Не используйте * если вы не отлаживаете или не извлекаете строки (строки) в ассоциативные массивы, иначе изменения схемы (столбцы ADD / DROP / переупорядочения) могут привести к неприятным ошибкам приложения. Кроме того, если вы укажете список столбцов, который вам нужен в вашем результирующем наборе, планировщик запросов MySQL часто может оптимизировать запрос.

Плюсы:

  1. Когда вы добавляете / удаляете столбцы, вам не нужно вносить изменения, когда вы использовали SELECT *
  2. Короче писать
  3. Вы также видите ответы, поэтому SELECT * -usage может быть оправданным?

Минусы:

  1. Вы возвращаете больше данных, чем вам нужно. Предположим, вы добавили столбец VARBINARY, который содержит 200 тыс. Строк. Вам нужны только эти данные в одном месте для одной записи - с помощью SELECT * вы можете в конечном итоге вернуть 2 МБ на 10 строк, которые вам не нужны
  2. Явно о том, какие данные используются
  3. Указание столбцов означает, что вы получаете сообщение об ошибке при удалении столбца
  4. Обработчик запросов должен выполнить еще одну работу - выяснить, какие столбцы существуют в таблице (спасибо @vinodadhikary)
  5. Вы можете найти, где колонка используется более легко
  6. Вы получаете все столбцы в соединениях, если используете SELECT *
  7. Вы не можете безопасно использовать порядковые ссылки (хотя использование порядковых ссылок для столбцов - это плохая практика сама по себе)
  8. В сложных запросах с полями TEXT запрос может быть замедлен с помощью менее оптимальной обработки таблицы temp

ВЫБЕРИТЕ ГДЕ

запрос

SELECT * FROM stack WHERE username = "admin" AND password = "admin";

Результат

+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
+------+----------+----------+
1 row in set (0.00 sec) 

Запрос с вложенным SELECT в предложении WHERE

Предложение WHERE может содержать любой действительный SELECT для записи более сложных запросов. Это «вложенный» запрос

запрос

Вложенные запросы обычно используются для возврата одиночных атомных значений из запросов для сопоставлений.

SELECT title FROM books WHERE author_id = (SELECT id FROM authors WHERE last_name = 'Bar' AND first_name = 'Foo');

Выбирает все имена пользователей без адреса электронной почты

SELECT * FROM stack WHERE username IN (SELECT username FROM signups WHERE email IS NULL);

Отказ от ответственности: рассмотрите возможность использования объединений для повышения производительности при сравнении всего набора результатов.

SELECT с 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» где угодно:

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   |
+----+-----------+

Начинается с "adm":

SELECT * FROM stack WHERE username LIKE "adm%";
+----+----------+
| id | username |
+----+----------+
|  1 | admin    |
|  3 | adm      |
|  6 | adm now  |
+----+----------+

Заканчивается знаком «adm»:

SELECT * FROM stack WHERE username LIKE "%adm"; 
+----+----------+
| id | username |
+----+----------+
|  3 | adm      |
+----+----------+

Так же, как символ % в предложении LIKE соответствует любому количеству символов, символ _ соответствует только одному символу. Например,

SELECT * FROM stack WHERE username LIKE "adm_n"; 
+----+----------+
| id | username |
+----+----------+
|  1 | admin    |
+----+----------+

Замечания по производительности Если есть указатель на username , то

  • LIKE 'adm' выполняет то же самое, что и `= 'adm'
  • LIKE 'adm% - это «диапазон», аналогичный BETWEEN..AND.. Он может эффективно использовать индекс в столбце.
  • LIKE '%adm' (или любой вариант с ведущим шаблоном) не может использовать какой-либо индекс. Поэтому он будет медленным. На таблицах со многими строками он, вероятно, будет настолько медленным, что бесполезен.
  • RLIKE ( REGEXP ) имеет тенденцию быть медленнее LIKE , но имеет больше возможностей.
  • Хотя MySQL предлагает индексирование FULLTEXT во многих типах таблицы и столбца, эти индексы FULLTEXT не используются для выполнения запросов с использованием LIKE .

SELECT с псевдонимом (AS)

SQL-псевдонимы используются для временного переименования таблицы или столбца. Они обычно используются для улучшения удобочитаемости.

запрос

SELECT username AS val FROM stack; 
SELECT username val FROM stack;

(Примечание: AS является синтаксически необязательным.)

Результат

+-------+
| val   |
+-------+
| admin |
| stack |
+-------+
2 rows in set (0.00 sec)

SELECT с предложением LIMIT

Запрос:

 SELECT *
   FROM Customers
  ORDER BY CustomerID 
  LIMIT 3;

Результат:

Пользовательский ИД Имя покупателя Контактное лицо Адрес город Почтовый индекс Страна
1

Альфредс Футтеркисте Мария Андерс Obere Str. 57 Берлин 12209 Германия
2 Ana Trujillo Emparedados y helados Ана Трухильо Avda. de la Constitución 2222 México DF 05021 Мексика
3 Антонио Морено Такерия Антонио Морено Mataderos 2312 México DF 05023 Мексика

Лучшая практика Всегда используйте ORDER BY при использовании LIMIT ; в противном случае строки, которые вы получите, будут непредсказуемыми.

Запрос:

 SELECT *
   FROM Customers
  ORDER BY CustomerID 
  LIMIT 2,1;

Объяснение:

Когда предложение LIMIT содержит два числа, оно интерпретируется как LIMIT offset,count . Итак, в этом примере запрос пропускает две записи и возвращает один.

Результат:

Пользовательский ИД Имя покупателя Контактное лицо Адрес город Почтовый индекс Страна
3 Антонио Морено Такерия Антонио Морено Mataderos 2312 México DF 05023 Мексика

Замечания:

Значения в предложениях LIMIT должны быть константами; они могут не быть значениями столбцов.

ВЫБЕРИТЕ с DISTINCT

Предложение DISTINCT после SELECT исключает дубликаты строк из набора результатов.

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 работает во всех столбцах, чтобы предоставлять результаты, а не отдельные столбцы. Последнее часто является заблуждением новых разработчиков SQL. Короче говоря, значимость на уровне строки результирующего набора имеет значение, а не отчетность на уровне столбца. Чтобы визуализировать это, посмотрите на «Audi A1» в приведенном выше наборе результатов.

Для более поздних версий MySQL DISTINCT имеет последствия с его использованием наряду с ORDER BY . Параметр ONLY_FULL_GROUP_BY вступает в игру, как показано на следующей странице руководства по MySQL, озаглавленной « Обработка MySQL GROUP BY» .

SELECT с LIKE (_)

Символ _ в шаблоне предложения LIKE соответствует одному символу.

запрос

SELECT username FROM users WHERE users LIKE 'admin_';

Результат

+----------+
| username |  
+----------+
| admin1   |
| admin2   |
| admin-   |
| adminA   |
+----------+

SELECT с CASE или IF

запрос

SELECT st.name,
       st.percentage, 
       CASE WHEN st.percentage >= 35 THEN 'Pass' ELSE 'Fail' END AS `Remark` 
FROM student AS st ;

Результат

+--------------------------------+
|   name   | percentage | Remark |
+--------------------------------+
|   Isha   |     67     |  Pass  |
|   Rucha  |     28     |  Fail  |
|   Het    |     35     |  Pass  |
|   Ansh   |     92     |  Pass  |
+--------------------------------+

Или с 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')

Это означает: IF st.percentage> = 35 имеет значение TRUE, а затем возвращает 'Pass' ELSE return 'Fail'

ВЫБЕРИТЕ МЕЖДУ

Вы можете использовать предложение BETWEEN, чтобы заменить комбинацию условий «больше, чем равных И меньше, чем равных».

Данные

+----+-----------+
| id | username  |
+----+-----------+
|  1 | admin     |
|  2 | root      |
|  3 | toor      |
|  4 | mysql     |
|  5 | thanks    |
|  6 | java      |
+----+-----------+

Запрос с операторами

SELECT * FROM stack WHERE id >= 2 and id <= 5; 

Похожие запросы: BETWEEN

SELECT * FROM stack WHERE id BETWEEN 2 and 5; 

Результат

+----+-----------+
| id | username  |
+----+-----------+
|  2 | root      |
|  3 | toor      |
|  4 | mysql     |
|  5 | thanks    |
+----+-----------+
4 rows in set (0.00 sec)

Заметка

BETWEEN использует >= и <= , not > и < .

Использование НЕ МЕЖДУ

Если вы хотите использовать негатив, вы можете использовать NOT . Например :

SELECT * FROM stack WHERE id NOT BETWEEN 2 and 5; 

Результат

+----+-----------+
| id | username  |
+----+-----------+
|  1 | admin     |
|  6 | java      |
+----+-----------+
2 rows in set (0.00 sec)

Заметка

NOT BETWEEN использует > и < и не >= и <= То есть WHERE id NOT BETWEEN 2 and 5 совпадает с WHERE (id < 2 OR id > 5) .

Если у вас есть индекс в столбце, который вы используете в поиске BETWEEN , MySQL может использовать этот индекс для сканирования диапазона.

SELECT с диапазоном дат

SELECT ... WHERE dt >= '2017-02-01'
             AND dt  < '2017-02-01' + INTERVAL 1 MONTH

Конечно, это можно сделать с BETWEEN и включением 23:59:59 . Но эта модель имеет следующие преимущества:

  • Вы не предварительно рассчитали дату окончания (которая часто является точной длиной с самого начала)
  • Вы не включаете обе конечные точки (как это делает BETWEEN ), и не вводите «23: 59: 59», чтобы избежать этого.
  • Он работает для DATE , TIMESTAMP , DATETIME и даже для DATETIME(6) включенных в микросекунду.
  • Он заботится о високосных днях, конце года и т. Д.
  • Он удобен для индекса (так же BETWEEN ).


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow