Формат SQL

Инструмент форматирования и украшения SQL операторов

Обзор инструмента: Инструмент Формата SQL

Этот инструмент предоставляет форматирование, украшение и сжатие SQL операторов. Совместим с множественными диалектами баз данных, предлагает подсветку синтаксиса, обнаружение ошибок и интеллектуальное форматирование для улучшения читаемости и поддерживаемости SQL кода.

Что такое Инструмент Формата SQL

Инструмент Формата SQL форматирует данные с единым отступом и разметкой для лучшей читаемости.

Как пользоваться

  1. Вставьте содержимое для форматирования.
  2. Выберите отступы и опции.
  3. Отформатируйте и скопируйте результат.

Частые сценарии

  • Унификация стиля перед публикацией
  • Поиск ошибок структуры или синтаксиса
  • Чистые фрагменты для документации

❓ Частые вопросы

В1: Форматирование не удалось?
О: Проверьте синтаксис перед форматированием.

В2: Можно минифицировать?
О: Используйте компактный режим при наличии.

В3: Сохранить комментарии?
О: Выберите режим с сохранением комментариев.

✨ Основные Характеристики

  • 🎨 Интеллектуальное Форматирование : Автоматическое форматирование с подходящими отступами
  • 🗜️ Сжатие SQL : Удаляет ненужные пробелы для оптимизации
  • 🌐 Множественные Диалекты : Совместим с MySQL, PostgreSQL, SQL Server, Oracle
  • 📋 Копирование Одним Кликом : Отформатированный код может быть скопирован напрямую
  • 🔍 Обнаружение Ошибок : Автоматически идентифицирует проблемы синтаксиса

📖 Примеры Использования

Форматирование Базового Запроса

Входной SQL (неотформатированный):

select u.id,u.имя,u.email,p.заголовок from пользователи u inner join посты p on u.id=p.пользователь_id where u.активен=1 and p.опубликован=1 order by p.дата_создания desc limit 10;

Отформатированный SQL:

SELECT 
    u.id,
    u.имя,
    u.email,
    p.заголовок
FROM пользователи u
INNER JOIN посты p ON u.id = p.пользователь_id
WHERE u.активен = 1
    AND p.опубликован = 1
ORDER BY p.дата_создания DESC
LIMIT 10;

Форматирование Сложного Запроса

Входной SQL:

with месячные_продажи as (select extract(year from дата_продажи) as год,extract(month from дата_продажи) as месяц,sum(общая_сумма) as общие_продажи from продажи where дата_продажи >= '2024-01-01' group by extract(year from дата_продажи),extract(month from дата_продажи)),рейтинг_продаж as (select год,месяц,общие_продажи,rank() over (order by общие_продажи desc) as рейтинг from месячные_продажи) select v.год,v.месяц,v.общие_продажи,v.рейтинг,case when v.рейтинг <= 3 then 'Топ 3' when v.рейтинг <= 6 then 'Средний' else 'Низкий' end as категория from рейтинг_продаж v order by v.общие_продажи desc;

Отформатированный SQL:

WITH месячные_продажи AS (
    SELECT 
        EXTRACT(YEAR FROM дата_продажи) AS год,
        EXTRACT(MONTH FROM дата_продажи) AS месяц,
        SUM(общая_сумма) AS общие_продажи
    FROM продажи
    WHERE дата_продажи >= '2024-01-01'
    GROUP BY 
        EXTRACT(YEAR FROM дата_продажи),
        EXTRACT(MONTH FROM дата_продажи)
),
рейтинг_продаж AS (
    SELECT 
        год,
        месяц,
        общие_продажи,
        RANK() OVER (ORDER BY общие_продажи DESC) AS рейтинг
    FROM месячные_продажи
)
SELECT 
    v.год,
    v.месяц,
    v.общие_продажи,
    v.рейтинг,
    CASE 
        WHEN v.рейтинг <= 3 THEN 'Топ 3'
        WHEN v.рейтинг <= 6 THEN 'Средний'
        ELSE 'Низкий'
    END AS категория
FROM рейтинг_продаж v
ORDER BY v.общие_продажи DESC;

🎯 Сценарии Применения

1. Разработка Приложений

-- Система управления пользователями и разрешениями
CREATE TABLE пользователи (
    id SERIAL PRIMARY KEY,
    имя VARCHAR(100) NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    хеш_пароля VARCHAR(255) NOT NULL,
    активен BOOLEAN DEFAULT TRUE,
    дата_создания TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    дата_обновления TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE роли (
    id SERIAL PRIMARY KEY,
    название VARCHAR(50) UNIQUE NOT NULL,
    описание TEXT,
    дата_создания TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE разрешения (
    id SERIAL PRIMARY KEY,
    название VARCHAR(100) UNIQUE NOT NULL,
    ресурс VARCHAR(100) NOT NULL,
    действие VARCHAR(50) NOT NULL,
    описание TEXT
);

CREATE TABLE пользователь_роли (
    пользователь_id INTEGER REFERENCES пользователи(id) ON DELETE CASCADE,
    роль_id INTEGER REFERENCES роли(id) ON DELETE CASCADE,
    дата_назначения TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (пользователь_id, роль_id)
);

CREATE TABLE роль_разрешения (
    роль_id INTEGER REFERENCES роли(id) ON DELETE CASCADE,
    разрешение_id INTEGER REFERENCES разрешения(id) ON DELETE CASCADE,
    PRIMARY KEY (роль_id, разрешение_id)
);

-- Запрос для проверки разрешений пользователя
SELECT DISTINCT
    u.id AS пользователь_id,
    u.имя AS имя_пользователя,
    p.название AS разрешение,
    p.ресурс,
    p.действие
FROM пользователи u
INNER JOIN пользователь_роли ur ON u.id = ur.пользователь_id
INNER JOIN роли r ON ur.роль_id = r.id
INNER JOIN роль_разрешения rp ON r.id = rp.роль_id
INNER JOIN разрешения p ON rp.разрешение_id = p.id
WHERE u.активен = TRUE
    AND u.email = $1
ORDER BY p.ресурс, p.действие;

2. Анализ Данных и Отчеты

-- Отчет о продажах с временным анализом
WITH данные_продаж AS (
    SELECT 
        v.id,
        v.дата_продажи,
        v.общая_сумма,
        c.имя AS имя_клиента,
        c.сегмент,
        p.название AS название_продукта,
        p.категория,
        vp.количество,
        vp.цена_за_единицу,
        EXTRACT(YEAR FROM v.дата_продажи) AS год,
        EXTRACT(MONTH FROM v.дата_продажи) AS месяц,
        EXTRACT(QUARTER FROM v.дата_продажи) AS квартал
    FROM продажи v
    INNER JOIN клиенты c ON v.клиент_id = c.id
    INNER JOIN продажа_товары vp ON v.id = vp.продажа_id
    INNER JOIN товары p ON vp.товар_id = p.id
    WHERE v.дата_продажи >= DATE_TRUNC('year', CURRENT_DATE - INTERVAL '2 years')
),
месячные_метрики AS (
    SELECT 
        год,
        месяц,
        COUNT(DISTINCT id) AS общие_продажи,
        SUM(общая_сумма) AS общий_доход,
        AVG(общая_сумма) AS средний_чек,
        COUNT(DISTINCT имя_клиента) AS уникальные_клиенты
    FROM данные_продаж
    GROUP BY год, месяц
),
месячный_рост AS (
    SELECT 
        *,
        LAG(общий_доход) OVER (ORDER BY год, месяц) AS доход_предыдущий_месяц,
        ROUND(
            ((общий_доход - LAG(общий_доход) OVER (ORDER BY год, месяц)) / 
             NULLIF(LAG(общий_доход) OVER (ORDER BY год, месяц), 0)) * 100, 2
        ) AS процент_роста
    FROM месячные_метрики
)
SELECT 
    год,
    месяц,
    TO_CHAR(DATE_FROM_PARTS(год, месяц, 1), 'Month YYYY') AS период,
    общие_продажи,
    ROUND(общий_доход, 2) AS общий_доход,
    ROUND(средний_чек, 2) AS средний_чек,
    уникальные_клиенты,
    COALESCE(процент_роста, 0) AS процент_роста,
    CASE 
        WHEN процент_роста > 10 THEN 'Отличный'
        WHEN процент_роста > 0 THEN 'Положительный'
        WHEN процент_роста = 0 THEN 'Стабильный'
        ELSE 'Отрицательный'
    END AS статус_роста
FROM месячный_рост
ORDER BY год DESC, месяц DESC;

3. Оптимизация Производительности

-- Анализ производительности запросов
EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON)
SELECT 
    u.id,
    u.имя,
    u.email,
    COUNT(p.id) AS общие_посты,
    MAX(p.дата_создания) AS последний_пост,
    AVG(p.просмотры) AS средние_просмотры
FROM пользователи u
LEFT JOIN посты p ON u.id = p.пользователь_id 
    AND p.опубликован = TRUE
    AND p.дата_создания >= CURRENT_DATE - INTERVAL '1 year'
WHERE u.активен = TRUE
GROUP BY u.id, u.имя, u.email
HAVING COUNT(p.id) > 0
ORDER BY общие_посты DESC, средние_просмотры DESC
LIMIT 50;

-- Создание индексов для оптимизации
CREATE INDEX CONCURRENTLY idx_посты_пользователь_опубликован_дата 
ON посты (пользователь_id, опубликован, дата_создания DESC)
WHERE опубликован = TRUE;

CREATE INDEX CONCURRENTLY idx_пользователи_активен_имя 
ON пользователи (активен, имя)
WHERE активен = TRUE;

-- Анализ использования индексов
SELECT 
    schemaname,
    tablename,
    indexname,
    idx_scan AS использования_индекса,
    idx_tup_read AS прочитанные_кортежи,
    idx_tup_fetch AS извлеченные_кортежи,
    ROUND(
        CASE 
            WHEN idx_scan = 0 THEN 0
            ELSE (idx_tup_fetch::FLOAT / idx_scan)
        END, 2
    ) AS эффективность_индекса
FROM pg_stat_user_indexes
WHERE schemaname = 'public'
ORDER BY idx_scan DESC, эффективность_индекса DESC;

4. Миграция и Обслуживание Данных

-- Скрипт миграции данных
BEGIN;

-- Резервная копия текущей структуры
CREATE TABLE пользователи_резерв AS 
SELECT * FROM пользователи;

-- Добавить новую колонку
ALTER TABLE пользователи 
ADD COLUMN телефон VARCHAR(20),
ADD COLUMN дата_последнего_входа TIMESTAMP,
ADD COLUMN попытки_входа INTEGER DEFAULT 0;

-- Мигрировать существующие данные
UPDATE пользователи 
SET дата_последнего_входа = дата_обновления
WHERE дата_обновления IS NOT NULL;

-- Создать новую таблицу аудита
CREATE TABLE аудит_пользователей (
    id SERIAL PRIMARY KEY,
    пользователь_id INTEGER NOT NULL,
    действие VARCHAR(50) NOT NULL,
    предыдущие_данные JSONB,
    новые_данные JSONB,
    ответственный_пользователь INTEGER,
    дата_действия TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    ip_источник INET
);

-- Функция триггера для аудита
CREATE OR REPLACE FUNCTION fn_аудит_пользователей()
RETURNS TRIGGER AS $$
BEGIN
    IF TG_OP = 'INSERT' THEN
        INSERT INTO аудит_пользователей (
            пользователь_id, действие, новые_данные, ответственный_пользователь
        ) VALUES (
            NEW.id, 'INSERT', row_to_json(NEW), NEW.id
        );
        RETURN NEW;
    ELSIF TG_OP = 'UPDATE' THEN
        INSERT INTO аудит_пользователей (
            пользователь_id, действие, предыдущие_данные, новые_данные, ответственный_пользователь
        ) VALUES (
            NEW.id, 'UPDATE', row_to_json(OLD), row_to_json(NEW), NEW.id
        );
        RETURN NEW;
    ELSIF TG_OP = 'DELETE' THEN
        INSERT INTO аудит_пользователей (
            пользователь_id, действие, предыдущие_данные
        ) VALUES (
            OLD.id, 'DELETE', row_to_json(OLD)
        );
        RETURN OLD;
    END IF;
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

-- Создать триггер
CREATE TRIGGER tg_аудит_пользователей
    AFTER INSERT OR UPDATE OR DELETE ON пользователи
    FOR EACH ROW EXECUTE FUNCTION fn_аудит_пользователей();

-- Валидировать миграцию
DO $$
DECLARE
    общий_оригинал INTEGER;
    общий_мигрированный INTEGER;
BEGIN
    SELECT COUNT(*) INTO общий_оригинал FROM пользователи_резерв;
    SELECT COUNT(*) INTO общий_мигрированный FROM пользователи;
    
    IF общий_оригинал != общий_мигрированный THEN
        RAISE EXCEPTION 'Ошибка миграции: количество не совпадает. Оригинал: %, Мигрированный: %', 
            общий_оригинал, общий_мигрированный;
    END IF;
    
    RAISE NOTICE 'Миграция завершена успешно. Общее количество записей: %', общий_мигрированный;
END $$;

COMMIT;

🔧 Технические Детали

Поддерживаемые Диалекты SQL

MySQL:

  • Специфический синтаксис: LIMIT, AUTO_INCREMENT
  • Функции: CONCAT(), DATE_FORMAT()
  • Типы данных: TINYINT, MEDIUMTEXT

PostgreSQL:

  • Специфический синтаксис: SERIAL, RETURNING
  • Функции: EXTRACT(), GENERATE_SERIES()
  • Продвинутые типы: JSONB, ARRAY, UUID

SQL Server:

  • Специфический синтаксис: TOP, IDENTITY
  • Функции: DATEPART(), STRING_AGG()
  • Возможности: CTE, MERGE, OUTPUT

Oracle:

  • Специфический синтаксис: ROWNUM, DUAL
  • Функции: DECODE(), NVL()
  • Возможности: CONNECT BY, PIVOT

Правила Форматирования

Отступы:

  • 4 пробела для каждого уровня отступа
  • Подзапросы отступаются соответственно
  • Предложения выравниваются вертикально

Переносы Строк:

  • Каждое основное предложение на новой строке
  • Списки колонок разбиваются при необходимости
  • JOIN'ы на отдельных строках

Капитализация:

  • Ключевые слова SQL в верхнем регистре
  • Имена таблиц и колонок сохраняются
  • Функции в верхнем регистре

💡 Советы по Использованию

  • Читаемость : Используйте последовательное форматирование для облегчения поддержки
  • Производительность : Рассмотрите сжатие для запросов в продакшене
  • Версионирование : Ведите историю изменений в SQL скриптах
  • Документация : Добавляйте объяснительные комментарии в сложные запросы

⚠️ Важные Замечания

  • Резервное Копирование : Всегда делайте резервную копию перед выполнением скриптов модификации
  • Тестирование : Тестируйте запросы в среде разработки сначала
  • Разрешения : Проверьте необходимые разрешения перед выполнением
  • Транзакции : Используйте транзакции для критических операций

🚀 Как Использовать

  1. Ввод SQL : Вставьте SQL код в область ввода
  2. Выбор Операции : Выберите "Форматировать" или "Сжать"
  3. Настройка Диалекта : Выберите подходящий диалект SQL
  4. Проверка Результатов : Отформатированный SQL появляется в области вывода
  5. Использование Копирования : Нажмите "Копировать" для использования отформатированного кода

Совет : Этот инструмент обрабатывает локально на стороне клиента и не выполняет SQL запросы, гарантируя безопасность ваших данных.