May 29, 2023

Основы SQL 

Основные команды в SHELL:

  • \! chcp 1251 фикс кодировки
  • \l список баз данных
  • \c подключает оболочку к серверу MySQL и назначает
    глобальный сеанс.
  • \d имя таблицы подключиться к таблице
  • \dt имя_таблицы просмотр

Работа с базами данных:

  • CREATE DATABASE имя_базы_данных;
  • DROP DATABASE имя_базы_данных;

Создание таблицы:

  • CREATE TABLE имя таблицы;
  • DROP TABLE имя_таблицы;
  • CREATE TABLE users(
    id BIGSERIAL NOT NULL PRIMARY KEY,
    first_name VARCHAR(50) NOT NULL,
    last_name VARCHAR(50) NOT NULL,
    gender VARCHAR(50) NOT NULL,
    email VARCHAR(50),
    date_of_birth DATE NOT NULL,
    country_of_birth VARCHAR(50) NOT NULL
    );

Добавление данных в таблицу:

  • INSERT INTO users(
    first_name, last_name, gender, email, date_of_birth)
    VALUES('Ann', 'Black', 'FEMALE', 'ann@gmail.com', '1999-01-01');

Импорт из файла:

Пример файла

Запрос SQL обычно состоит из нескольких частей, которые могут располагаться в разном порядке, но обычно они следуют в следующем порядке:

  1. SELECT - определяет, какие столбцы из таблицы будут выбраны для вывода в результате запроса.
  2. FROM - указывает таблицу или таблицы, из которых нужно выбрать данные.
  3. WHERE - определяет условия для фильтрации строк.
  4. GROUP BY - группирует строки по заданным столбцам.
  5. HAVING - определяет условия для фильтрации групп.
  6. ORDER BY - сортирует результаты запроса по заданным столбцам.
  7. LIMIT - ограничивает количество строк, возвращаемых запросом.

Запросы, выборка данных:

  • SELECT email FROM users; все почты из таблицы
  • SELECT first_name, last_name FROM users; имена и фамилии из таблицы
  • SELECT DISTINCT country_of_birth FROM users ORDER BY country_of_birth DESC; поиск уникальных стран с сортировкой по стране в обратном порядке
  • SELECT * FROM users LIMIT 10 OFFSET 5; вывести 10 строк со сдвигом 5
  • SELECT * FROM users FETCH FIRST 5 ROW ONLY; первые пять строк другим способом
  • SELECT * FROM users WHERE gender = 'Female' and (country_of_birth = 'Russia' OR country_of_birth = 'China'); выбрать женщин из России или Китая
  • SELECT * FROM users WHERE country_of_birth IN ('China', 'Russia', 'Argentina'); метод IN более удобен для нескольких вариантов чем OR
  • SELECT * FROM users WHERE date_of_birth BETWEEN '1993-01-01' AND '1995-12-30'; выборка между двумя датами
  • SELECT * FROM users WHERE email LIKE '%@gmail.%'; выбрать все email с текстом @gmail. внутри
  • SELECT * FROM users WHERE email iLIKE 's%'; метод iLIKE игнорирует разницу заглавной и строчных букв
  • SELECT gender, COUNT(*) FROM users GROUP BY gender; подсчет кол-ва людей каждого гендера сгруппированных по гендеру
  • SELECT gender, COUNT(*) FROM users GROUP BY gender HAVING COUNT(*) > 10; вывести только тех чье кол-во больше 10
  • SELECT gender, COUNT(*) FROM users GROUP BY gender HAVING COUNT(*) > 10 ORDER BY count; вывести только тех чье кол-во больше 10 и отсортировать
  • SELECT first_name AS name, last_name AS surename FROM users; создать псевдоним/временное имя вместо имен колонок
  • SELECT COALESCE(email, 'not applicablle') FROM users; заменить пустые значения на значение 'not applicablle' или другое
  • SELECT COUNT(*) FROM users WHERE email IS NOT NULL and date_of_birth BETWEEN '1991-01-01' AND '1997-01-01'; просто посчитать кол-во человек по запросу

АГРЕГАТЫ И БАЗОВАЯ АРИФМЕТИКА:

  • SELECT MAX(price) FROM holiday; максимальное значение из колонки
  • SELECT MIN(price) FROM holiday; минимальное значение из колонки
  • SELECT ROUND(AVG(price)) FROM; holiday округленное среднее значение
  • SELECT SUM(price) FROM holiday; сумма всех значений
  • SELECT country, SUM(price) FROM holiday GROUP BY country ORDER BY SUM(price) DESC; сумма всех значений с сортировкой от максимального
  • SELECT country, SUM(price) FROM holiday WHERE country IN ('China','Russia','Brazil','Japan','Peru','Poland') GROUP BY country HAVING SUM(price)<70000 ORDER BY SUM(price) ASC LIMIT 5; сумма путевок в выбранных странах меньше 70000, с сортировкой и лимитом выдачи
  • + - / * ^(степень) %(деление по модулю)

РАБОТА С ДАТОЙ И ВРЕМЕНЕМ:

  • SELECT NOW(); текущее время
  • SELECT NOW()::DATE; выведет только дату 2023-05-24
  • SELECT NOW()::TIME; выведет только время 02:46:03.679377
  • SELECT NOW() - INTERVAL '1 YEAR 10 MONTH 10 DAYS'; выведет дату из прошлого, можно использовать + для будущей даты.
  • SELECT EXTRACT(MONTH FROM NOW()); выведет цифру месяца, также можно использовать YEAR, DAY, DOW(день недели)
  • SELECT first_name, date_of_birth, AGE(NOW(), date_of_birth) FROM users; узнать возраст

УДАЛЕНИЕ:

  • DELETE FROM users WHERE id = 1; удалить строку с id = 1
  • DELETE FROM users WHERE email LIKE '%google.com%'; удаляем всех у кого почта содержит google.com

ОБНОВЛЕНИЕ ДАННЫХ:

  • UPDATE users SET first_name = 'Mike', email = 'kimberle@mail.ru' WHERE id = 3; поменять почту и имя у пользователя с id 3 (обязательно условие иначе обновится все строки)

ОГРАНИЧЕНИЯ И ПРОВЕРКИ:

  • ALTER TABLE users ADD CONSTRAINT unique_email_address UNIQUE (email); добавляем ограничение, чтобы email был уникальным значением
  • ALTER TABLE users ADD CONSTRAINT gender_const CHECK (gender = 'Female OR gender = 'Male'); делаем проверку, чтобы gender был только Female или Male
  • INSERT INTO users( id, first_name, last_name, gender, email, date_of_birth) VALUES(3, 'Ann', 'Black', 'Female', 'ann@gmail.com', '1999-01-01') ON CONFLICT (id) DO NOTHING; если есть такой же id (id должен быть primary key, т.е выступает в роли ограничителя), то ничего не делать, т.е не вернется ошибка
  • INSERT INTO users( id, first_name, last_name, gender, email, date_of_birth) VALUES(3, 'Ann', 'Black', 'Female', 'ann@gmail.com', '1999-01-01') ON CONFLICT (id) DO UPDATE SET email = EXCLUDED.email; если есть такой же id (id должен быть primary key, т.е выступает в роли ограничителя), то исключить из проверки email и заменить только это поле. Называется UPSERT (UPDATE + INSERT).

PRIMARY KEYS:

  • ALTER TABLE users DROP CONSTRAINT users_pkey; удалям primary key
  • ALTER TABLE users ADD PRIMARY KEY(id); добавляем id как primary key

FOREGIN KEYS:

  • ALTER TABLE users ADD bike_id BIGINT REFERENCES bikes(id); добавляем внешний ключ (bike_id) в таблицу users, который будет ссылаться на поле id в таблице bikes;
  • ALTER TABLE users ADD UNIQUE(bike_id); делаем bike_id уникальным в таблице users (у каждого свой велосипед) Если вы хотите явно указать имя для ограничения, вы можете добавить его после ключевого слова "CONSTRAINT". Например: ALTER TABLE users ADD CONSTRAINT unique_bike_id UNIQUE(bike_id);

Объединение таблиц (JOINS):

  • INNER JOIN SELECT * FROM users JOIN bikes ON users.bike_id = bikes.id; выбрать всех юзеров у кого есть байк
  • LEFT JOIN SELECT * FROM users LEFT JOIN bikes ON users.bike_id = bikes.id; выбрать всю таблицу слева и добавить значения из правой таблицы, в нашем случае будет много пустых значений, т.к велосипед есть только у 1 работника, поэтому можно отфильтровать:
    SELECT * FROM users LEFT JOIN bikes ON users.bike_id = bikes.id WHERE bike_id IS NOT NULL;
  • RIGHT JOIN SELECT * FROM users RIGHT JOIN bikes ON users.bike_id = bikes.id; выведет полностью правую таблицу и заполнит, общими данными из левой, если они есть
  • FULL OUTER JOIN SELECT * FROM users FULL OUTER JOIN bikes ON users.bike_id = bikes.id; полностью две таблицы

УНИКАЛЬНЫЕ ИДЕНТИФИКАТОРЫ UUID:

  • CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; сначала устанавливаем расширение
  • SELECT uuid_generate_v4(); генерация рандомного id с помощью функции
  • INSERT INTO passport (passport_serial, issue_date, expire_date, country_of_issue) VALUES (uuid_generate_v4(), '2019_03_19', '2045_03_19', 'UK'); генерация рандомного uuid при заполнение таблицы