genbodev
1/23/2019 - 3:31 PM

Фишки MySQL

/* Создать запись в таблице при условии, что такой записи ещё нет */
/* Полезно, если подготавливается миграция, но на боевой БД кто-то возможно уже создал такую запись */
/* Использовать только, если на либом из полей нет уникального ключа */
INSERT INTO ncities (country_id, name_ru, name_en) 
SELECT * FROM (SELECT 156, 'Казачинское', 'Kazachinskoe') AS tmp 
WHERE NOT EXISTS (
  SELECT country_id FROM ncities WHERE country_id = 156 AND name_ru = 'Казачинское' AND name_en = 'Kazachinskoe'
) LIMIT 1;

/* Выбрать последние 30 записей */
SELECT * FROM aviatickets ORDER BY id DESC LIMIT 30;

/* Подстановка искомого столбца на первое место */
SELECT ticket_adv_params, t.* FROM aviatickets AS t WHERE id_service = 1215813;

/* Поиск по длине символов в поле */
SELECT LENGTH(ticket_adv_params), ticket_adv_params, t.* FROM aviatickets AS t WHERE ticket_adv_params IS NOT NULL AND LENGTH(ticket_adv_params) < 60;

/* Поиск по субстроке */
SELECT * FROM aviatickets WHERE ticket_adv_params LIKE '%<p>%' AND ticket_adv_params LIKE '%Sabre%' AND add_Date > '2019-01-01';
/* http://zetcode.com/databases/mysqltutorial/exportimport/ */

/* Для начала нужно узнать, какая директория доступна для записи, т.к. сервер может быть запущен с --secure-file-priv которая ограничивает какие директории вы можете использовать с загружаемыми файлами */
SHOW VARIABLES LIKE 'secure_file_priv'; 

/* Полученную директорию используем для сохранения файла */
SELECT * FROM avia3side_transmitted INTO OUTFILE '/var/lib/mysql-files/avia3side_transmitted';

/* Удалить файл средствами mysql не возможно, поэтому можно генерировать разные имена, например через php */
$fileName = 'avia3side_transmitted_' . date("d_m_Y_h_i_s");
SELECT * FROM avia3side_transmitted INTO OUTFILE '/var/lib/mysql-files/avia3side_transmitted';

/* Или средствами mysql */
SET NAMES 'utf8';
SELECT CONCAT("SELECT * FROM avia3side_transmitted INTO OUTFILE '/var/lib/mysql-files/avia3side-transmitted-", REPLACE(REPLACE(NOW(), ' ', '-'), ':', '-'), "'");
SET @sql_query = CONCAT("SELECT * FROM avia3side_transmitted INTO OUTFILE '/var/lib/mysql-files/avia3side-transmitted-", REPLACE(REPLACE(NOW(), ' ', '-'), ':', '-'), "'");
PREPARE s1 FROM @sql_query;
EXECUTE s1;
DROP PREPARE s1;

/* Теперь процедура импорта. Она заключается в удалении таблицы и загрузки файла */
DELETE FROM avia3side_transmitted;
LOAD DATA INFILE '/var/lib/mysql-files/avia3side_transmitted' INTO TABLE avia3side_transmitted;
Хм.. Могу посоветовать такой вариант:
минуту
Для начала зайди в настройки OpenServer на вкладку модули
Проверь, что у тебя используется MariaDB
Она считается более быстрой чем обычный mysql
Затем выполни запросы:
SET GLOBAL general_log = 1; /* Включает логгирование */
SET GLOBAL log_output = 'table'; /* Для логгирования будем использовать не файл, а прямо БД */
(изменено)
SELECT * FROM mysql.general_log; /* Покажет лог */

Можно писать в файл, но похоже OpenServer это то ещё не подконтрольное г
-- Одним запросом вставит строку \ запомнит идентификатор \ тспользует его далее

INSERT INTO table1 (title,userid) VALUES ('test', 1); 
SET @last_id_in_table1 = LAST_INSERT_ID();
INSERT INTO table2 (parentid,otherid,userid) VALUES (@last_id_in_table1, 4, 1); 

-- or

INSERT INTO table1 (title,userid) VALUES ('test', 1); 
INSERT INTO table2 (parentid,otherid,userid) VALUES (LAST_INSERT_ID(), 4, 1); 
SELECT MAX(id) FROM table1;
/* Поиск связанных ключей таблицы users поля id по БД starliner */
SELECT *
FROM
  information_schema.KEY_COLUMN_USAGE
WHERE
  REFERENCED_TABLE_NAME = 'users'
  AND REFERENCED_COLUMN_NAME = 'id'
  AND TABLE_SCHEMA = 'starliner';
// http://stepansuvorov.com/blog/2012/08/insert-on-duplicate-key-update/

UPDATE tbl_country SET price = CASE
WHEN code = 1 THEN 123;
WHEN code = 2 THEN 456;
…
END
WHERE code IN (1,2,…)
------------------------------------
INSERT INTO tbl_country
(code, price)
VALUES
(1, 123),
(2, 456),
…
ON DUPLICATE KEY UPDATE tbl_country.price = VALUES(price);
// http://yershov.com.ua/mysql/mysql-%D0%BE%D0%B4%D0%BD%D0%BE%D0%B2%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9-select-%D0%B8-update-%D0%BF%D1%80%D0%B8-%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B5-%D1%81-%D0%BE%D0%B4%D0%BD%D0%BE%D0%B9/

 
UPDATE table_1 AS tbl_1
    SET tbl_1.cnt = (
        SELECT COUNT(*) FROM table_1 AS tbl_2
        WHERE tbl_1.type = tbl_2.type
    );
    
    // Error: You can't specify target table 'tbl_1' for update in FROM clause
    
UPDATE table_1 AS tbl_1
    INNER JOIN(
        SELECT type, COUNT(*) AS cnt
        FROM table_1
        GROUP BY type
    ) AS tbl_2 USING(type)
SET tbl_1.cnt = tbl_2.cnt;
    
// Если таблица имеет записи с одинаковыми id_service то можно получить кол-во совпадений (кол-во в группе по id_service)
SELECT id_service, COUNT(*) AS count FROM aviatickets WHERE id < 1600000 GROUP BY id_service HAVING COUNT > 1 ORDER BY id DESC LIMIT 30;
-- Быстрый выбор рандомного значения
SELECT u.id FROM users u
JOIN ( SELECT RAND() * (SELECT MAX(id) FROM files) AS max_id ) AS m
WHERE u.id >= m.max_id
ORDER BY u.id ASC
LIMIT 1;
	    
-- С учётом таблицы, в которой есть список user_id и их нужно исключить
SELECT u.id FROM users u
JOIN ( SELECT RAND() * (SELECT MAX(id) FROM users) AS max_id ) AS m
WHERE u.id >= m.max_id
AND u.id NOT IN (SELECT user_id FROM users_preferences)
ORDER BY u.id ASC
LIMIT 1;