====5. Команда SELECT в MySQL==== ===Загальна структура команди SELECT=== SELECT [ [DISTINCT |DISTINCTROW | ALL] список [виразів |стовпців] [INTO {OUTFILE | DUMPFILE} ‘і'мя_файлу‘ опції експорту | змінна] [FROM таблиці [WHERE умова] [GROUP BY {ціле | і'мя_стовпчика | вираз} [ASC | DESC], ...] [HAVING умова] [ORDER BY {ціле | і'мя_стовпчика | вираз} [ASC| DESC], ...] [LIMIT [зсув,] рядків] [PROCEDURE і'мя_процедури] [FOR UPDATE | LOCK IN SHARE MODE]] ; ==Модифікатори команди SELECT== *STRAIGHT_JOIN – інформація для оптимізатора mysql: таблиці об'єднувати в тому порядку, в якому вони задані. Пр. SELECT STRAIGHT_JOIN … FROM tab1 JOIN tab2 ORDER BY tab.name; *SQL_BIG_RESULT (SQL_SMALL_RESULT) – повідомлення для оптимизатора, що результуюча таблиця буде мати багато (або мало) рядків. Використовують з GROUP BY або DISTINCT. *SQL_BIG_RESULT – MySQL використовує тимчасові таблиці на диску. *SQL_SMALL_RESULT – MySQL використовує швидкі тимчасові таблиці. Можна використати з GROUP BY або DISTINCT, щоб повідомити оптимізатору, що результат буде невеликим. Тоді MySQL замість сортування для збереження результуючої таблиці буде використовувати швидкі тимчасові таблиці. *SQL_CACHE – зберігати результати в кеш-запиті, *SQL_NO_CACHE – не зберігати результати в кеш-запитів, *SQL_BUFFER_RESULT – результат розмістити у тимчасову таблицю. Це дає можливість скоріше зняти блокування таблиці. Цей модифікатор корисний також у випадках, коли для пересилки результатів клієнту потрібно дуже багато часу. *SQL_CALC_FOUND_ROWS – підрахувати кількість рядків в результуючій таблиці, ігноруючи LIMIT. Цей результат потім можна отримати за допомогою команди SELECT FOUND_ROWS() *FOR UPDATE — рядки, які зчитуються в команді SELECT, блокуються для читання в інших сесіях. Команда UPDATE використовує таке саме блокування, коли зчитує дані з таблиці для оновлення. *LOCK IN SHARE MODE — рядки, які зчитуються, блокуються для запису в інших сесіях. Інші сесії ці рядки можуть читати, але змінювати їх можуть лише після завершення транзакції. Таким чином отримують «найсвіжіші» дані. Особливості команди SELECT в MySQL\\ * При використанні ключових слів потрібно точно дотримуватись їх порядку. * Наприклад, вираз HAVING повинен бути після виразів GROUP BY і перед виразами ORDER BY. * GROUP BY: рядки виводу сортуються відповідно з порядком, заданим в GROUP BY (як для ORDER BY). Можно також вказувати параметри ASC и DESC: SELECT a, COUNT(b) FROM t GROUP BY a DESC * Ключове слово AS виразу в SELECT присвоює псевдонім. Псевдонім використовується в якості імені стовпця і може використовуватись в ORDER BY або HAVING. Наприклад: SELECT CONCAT(last_name,', ',first_name) AS full_name FROM tab ORDER BY full_name; * Псевдоніми стовпців не можна використовувати у виразі WHERE ( тому що величини, які знаходяться у стовпцях на момент виконання WHERE можуть бути ще не визначені). * Оператор SELECT можна використати без FROM. Тобто, можна використати для обчислення виразів, в яких немає посилання на будь-яку таблицю. Наприклад: SELECT 1 + 1; -> 2 * У виразах ORDER BY і GROUP BY для посилань на стовпці можна використовувати імена стовпців, їх псевдоніми або їх позиції. Нумерація позицій стовпців починається з 1: SELECT college, region, city FROM T ORDER BY region, city; SELECT college, region AS r, city AS s FROM T ORDER BY r, s; SELECT college, region, city FROM T ORDER BY 2, 3; У виразі WHERE можна використовувати всі функції, які підтримуються в MySQL. Вираз HAVING може посилатись на будь-який стовпець або псевдонім, які вказані після SELECT. HAVING виконується останнім і без оптимізації. Не рекомендується використовувати умову HAVING, якщо вона може бути задана у WHERE. Наприклад, неправильно буде: SELECT col_name FROM tbl_name HAVING col_name > 0; Правильно: SELECT col_name FROM tbl_name WHERE col_name > 0; У версіях MySQL після 3.22.5 можна писати запити: SELECT user, MAX(salary) FROM users GROUP BY user HAVING MAX(salary)>10; В попередніх версіях MySQL замість цього можна було використовувати лише: SELECT user, MAX(salary) AS sum FROM users GROUP BY user HAVING sum>10; Для таблиці в FROM можна задати псевдонім (аліас): і'мя_таблиці [[AS] аліас] [USE INDEX (список_ключів)] [IGNORE INDEX (список_ключів)] * HIGH_PRIORITY – найвищий пріоритет. Оператор SELECT має більш високий пріоритет, ніж команда оновлення таблиці. Такі запити повинні виконуватись дуже швидко і зразу. Якщо таблиця заблокована для читання, то запит з SELECT HIGH_PRIORITY буде виконуватись навіть при існуванні команди оновлення, яка чекає поки таблиця звільниться. * В ORDER BY і GROUP BY можна використовувати імена стовпців, їх псевдонимі, або їх позиції (місце в результаті). * LIMIT [k,] n обмежує кількість рядків, які виводяться. Якщо задано 1 аргумент, то він задає максимальну кількість рядків. Якщо – 2, то перший задає зміщення початку, а другий – кількість рядків. Зміщення першого рядка =0. SELECT * FROM t LIMIT 5,10; -- рядки 6-15. SELECT * FROM t LIMIT 0,5 (= LIMIT 5); -- перші 5 рядків. PROCEDURE pr(.) – опція команди SELECT.\\ Виконується PROCEDURE pr(), вхідними даними для якої є результуюча таблиця команди SELECT. SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max_elements, [max_memory]]) SELECT * FROM charac PROCEDURE ANALYSE(5, 24); Field_name: world.charac\\ Min_value: A\\ Max_value: E\\ Min_length: 1\\ Max_length: 1 \\ Empties_or_zeros: 0\\ Nulls: 0\\ Avg_value_or_avg_length: 1.0000\\ Optimal_fieldtype: CHAR(1) NOT NULL\\ ===Оператор JOIN в MySQL=== Вираз FROM <таблиці> задає всі таблиці, з яких вибираються рядки. Якщо вказано більше, ніж одна таблиця, рекомендується виконати об'єднання JOIN. Для кожної таблиці можна вказати псевдонім. * t1 INNER JOIN t2 [умова_join]t1 * STRAIGHT_JOIN t2 -- інформація оптимізатору: «не міняти порядок таблиць» * t1 LEFT [OUTER] JOIN t2 [умова_join ] * t1 RIGHT [OUTER] JOIN t2 [умова_join] * t1 NATURAL [LEFT [OUTER]] JOIN t2 * t1 NATURAL [RIGHT [OUTER]] JOIN t2 де t1, t2 визначені, як: Ім'я_таблиці [[AS] alias] [USE INDEX (key_list)] [IGNORE INDEX (key_list)] умова_join визначена як: ON умова | USING (список_стовпців) NATURAL автоматично перевіряє рівність значень спільних стовпців * В частині ON не можна вказувати такі умови, які накладають обмеження на рядки в наборі результатів. Якщо необхідно вказати, які рядки повинні бути присутніми в результаті, це потрібно зробити у виразі WHERE. * Умовний оператор ON може містити умови в тій самій формі, як і у виразі WHERE. * Якщо запис для правої таблиці в частинах ON або USING в LEFT JOIN не знайдена, то для цієї таблиці використовується рядок, в якому всі стовпці мають значення NULL. Приклад. SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL; Команда знаходить всі рядки в таблиці t1 з величиною id, яка не присутня в таблиці t2. * USING (column_list) – задає список стовпців, які повинні існувати в обох таблицях. Вираз USING в: A LEFT JOIN B USING (C1, C2, C3, ...) еквівалентний такому виразу ON: A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3,... ===Експорт даних. Вивід результуючої таблиці в файл === Опція INTO OUTFILE 'Шлях і ім’я файлу' [FILEDS ...] [LINES ...] Цей файл створюється на сервері і перед цим не повинен існувати. Для використання цієї форми команди SELECT необхідно мати привілей FILE.\\ Форма SELECT ... INTO OUTFILE в першу чергу призначена для швидкого створення дампа таблиці на серверному комп'ютері.\\ FILEDS і LINES мають той же зміст, що і в команді LOAD DATA. \\ Команду SELECT… INTO OUTFILE можна використати для резервного копіювання, а LOAD DATA – для перенесення даних на інший сервер MySQL. \\ Якщо замість INTO OUTFILE використовується INTO DUMPFILE, то MySQL в файл запише лише один «довгий» рядок без символів завершення стовпців і рядків. Це дозволяє дані типу BLOB зберігати у файлі.\\ Файл, який був створений за допомогою INTO OUTFILE та INTO DUMPFILE буде доступний для читання всіма користувачами. \\ При використанні FOR UPDATE з обробником таблиць, які підтримують блокування сторінок/рядків, вибрані рядки будуь заблоковані для запису. Наприклад: SELECT * FROM Customers INTO OUTFILE 'C:/data/Customers.txt'; Після цього можна виконати ( інший користувач теж): LOAD DATA INFILE 'C:/data/Customers.txt' INTO TABLE Custom_copy; Приклад: SELECT a, b, a+b INTO OUTFILE "/tmp/result.text" FIELDS TERMINATED BY ',‘ LINES TERMINATED BY "\n" FROM test_table; ===Завантаження (імпорт) даних в таблицю з файлу=== LOAD DATA [LOCAL] INFILE 'Шлях в каталозі та ім’я файлу' [REPLACE або IGNORE] INTO TABLE <Ім’я таблиці> CHARACTER SET <кодування> [FIELDS [TERMINATED BY <Розділювач значень в рядку>] [ ENCLOSED BY <Символ, який обмежує значення даних>] [ LINES [TERMINATED BY <Розділювач рядків в файлі>] ] [(<Список стовпців>)] [SET <Ім’я стовпця> = <Вираз>,...]; Приклад. Будь-яким текстовим редактором підготувати дані в файлі Customers.txt. Потім LOAD DATA LOCAL INFILE 'C:/data/Customers.txt' INTO TABLE Customers CHARACTER SET cp1251; Щоб ігнорувати обмеження зовнішнього ключа, перед виконанням LOAD DATA потрібно виконати SET foreign_key_checks = 0 • LOCAL – файл знаходиться на клієнтському комп’ютері. • REPLACE – заміна існуючого рядка (з однаковим ключем), • IGNORE – ігнорування завантаження (з однаковим ключем) • FIELDS TERMINATED BY <Розділювач> – символ відокремлення значень. Пр. \t – символами табуляції. По замовчуванню – відокремлення комами. • ENCLOSED BY <Символ обмеження даних>. Якщо всі дані обмежені одинарними лапками, то \, якщо в лапках лише символьні дані, то OPTIONALLY ENCLOSED BY \ • Якщо FIELDS не задане, то по замовчуванню вважається: FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\‘ (значення розділені табуляцією без лапок). • LINES відсутній – рядки закінчуються символом переводу «\n». • (<Список стовпців>) – стовпці таблиці, в які завантажуються дані. Використовується, якщо файл містить дані не для всіх стовпців таблиці. ===Групові (агрегатні) функції=== *SUM() * AVG() * MAX() * MIN() * COUNT() * VAR_POP() (або VARIANCE() ) обчислює дисперсію значень стовпця. * STDDEV_POP() обчислює середньоквадратичне відхилення значень стовпця (квадратний корінь з дисперсії). * GROUP_CONCAT() об'єднує в один рядок значення стовпця, ігноруючи значення NULL. (Корисна функція !)\\ Можна також вказати додаткові параметри:\\ DISTINCT – виключає дублювання значень; \\ ORDER BY – упорядковує результат; \\ SEPARATOR – задає розділові знаки. \\ Наприклад, \\ SELECT GROUP_CONCAT(DISTINCT name ORDER BY name ASC SEPARATOR ';') FROM Customers;