sql
This commit is contained in:
+21
@@ -0,0 +1,21 @@
|
||||
# gym bro
|
||||
|
||||
``` text
|
||||
clients (ФИО, ДР, цель)
|
||||
│
|
||||
│ 1:N
|
||||
├──► workouts ──────► workout_types (справочник)
|
||||
│ │
|
||||
│ │ 1:N
|
||||
│ ├──► workout_exercises ──► exercises ──► workout_types
|
||||
│ │ │
|
||||
│ │ │ 1:N
|
||||
│ │ └──► sets ──► dropset_items
|
||||
│ │
|
||||
│ └──► cardio
|
||||
│
|
||||
└──► body_metrics
|
||||
│
|
||||
│ 1:N
|
||||
└──► body_metric_values ──► metric_types (справочник)
|
||||
```
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
ivan-igorevich@MacBook-Pro-16.local.32588
|
||||
+224
@@ -0,0 +1,224 @@
|
||||
-- ============================================================
|
||||
-- Gym Tracker — SQLite schema v2
|
||||
-- Гибкие справочники + мультиклиентская схема
|
||||
-- ============================================================
|
||||
|
||||
PRAGMA foreign_keys = ON;
|
||||
PRAGMA journal_mode = WAL;
|
||||
|
||||
-- ============================================================
|
||||
-- 1. КЛИЕНТЫ (люди, чьи тренировки ведём)
|
||||
-- ============================================================
|
||||
CREATE TABLE clients (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE, -- UUID для синхронизации
|
||||
full_name TEXT NOT NULL,
|
||||
birth_date TEXT, -- ISO8601 (YYYY-MM-DD)
|
||||
goal TEXT DEFAULT '', -- цель тренировок
|
||||
notes TEXT DEFAULT '',
|
||||
is_active INTEGER NOT NULL DEFAULT 1,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
||||
);
|
||||
|
||||
CREATE INDEX idx_clients_name ON clients(full_name);
|
||||
CREATE INDEX idx_clients_active ON clients(is_active);
|
||||
|
||||
-- ============================================================
|
||||
-- 2. СПРАВОЧНИК ТИПОВ ТРЕНИРОВОК
|
||||
-- ============================================================
|
||||
CREATE TABLE workout_types (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- 3. СПРАВОЧНИК УПРАЖНЕНИЙ
|
||||
-- ============================================================
|
||||
CREATE TABLE exercises (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE,
|
||||
workout_type_id INTEGER, -- FK на workout_types
|
||||
name TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
|
||||
FOREIGN KEY (workout_type_id) REFERENCES workout_types(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_exercises_name ON exercises(name);
|
||||
CREATE INDEX idx_exercises_type ON exercises(workout_type_id);
|
||||
|
||||
-- ============================================================
|
||||
-- 4. ТРЕНИРОВКИ
|
||||
-- ============================================================
|
||||
CREATE TABLE workouts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE,
|
||||
client_id INTEGER, -- FK на clients
|
||||
workout_type_id INTEGER, -- FK на workout_types
|
||||
start_time TEXT NOT NULL, -- ISO8601
|
||||
end_time TEXT, -- NULL = активная
|
||||
notes TEXT DEFAULT '',
|
||||
synced INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
|
||||
FOREIGN KEY (client_id) REFERENCES clients(id) ON DELETE SET NULL,
|
||||
FOREIGN KEY (workout_type_id) REFERENCES workout_types(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_workouts_client ON workouts(client_id);
|
||||
CREATE INDEX idx_workouts_start ON workouts(start_time);
|
||||
CREATE INDEX idx_workouts_synced ON workouts(synced);
|
||||
|
||||
-- ============================================================
|
||||
-- 5. УПРАЖНЕНИЯ ВНУТРИ ТРЕНИРОВКИ
|
||||
-- ============================================================
|
||||
CREATE TABLE workout_exercises (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE,
|
||||
workout_id INTEGER NOT NULL,
|
||||
exercise_id INTEGER, -- FK на exercises (может быть NULL)
|
||||
exercise_name TEXT NOT NULL, -- дублируем для истории
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
|
||||
FOREIGN KEY (workout_id) REFERENCES workouts(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (exercise_id) REFERENCES exercises(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_wex_workout ON workout_exercises(workout_id);
|
||||
CREATE INDEX idx_wex_exercise ON workout_exercises(exercise_id);
|
||||
CREATE INDEX idx_wex_name ON workout_exercises(exercise_name);
|
||||
|
||||
-- ============================================================
|
||||
-- 6. ПОДХОДЫ
|
||||
-- ============================================================
|
||||
CREATE TABLE sets (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE,
|
||||
workout_exercise_id INTEGER NOT NULL,
|
||||
is_dropset INTEGER NOT NULL DEFAULT 0,
|
||||
weight REAL,
|
||||
reps INTEGER,
|
||||
rating INTEGER CHECK (rating BETWEEN 1 AND 5),
|
||||
notes TEXT DEFAULT '',
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
timestamp TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
|
||||
FOREIGN KEY (workout_exercise_id) REFERENCES workout_exercises(id) ON DELETE CASCADE,
|
||||
|
||||
CHECK (
|
||||
(is_dropset = 0 AND weight IS NOT NULL AND reps IS NOT NULL) OR
|
||||
(is_dropset = 1 AND weight IS NULL AND reps IS NULL)
|
||||
)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_sets_wex ON sets(workout_exercise_id);
|
||||
CREATE INDEX idx_sets_timestamp ON sets(timestamp);
|
||||
|
||||
-- ============================================================
|
||||
-- 7. ЭЛЕМЕНТЫ ДРОП-СЕТА
|
||||
-- ============================================================
|
||||
CREATE TABLE dropset_items (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
set_id INTEGER NOT NULL,
|
||||
weight REAL NOT NULL,
|
||||
reps INTEGER NOT NULL,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
FOREIGN KEY (set_id) REFERENCES sets(id) ON DELETE CASCADE,
|
||||
CHECK (weight > 0 AND reps > 0)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_dropset_set ON dropset_items(set_id);
|
||||
|
||||
-- ============================================================
|
||||
-- 8. КАРДИО
|
||||
-- ============================================================
|
||||
CREATE TABLE cardio (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE,
|
||||
workout_id INTEGER NOT NULL,
|
||||
cardio_type TEXT NOT NULL CHECK (cardio_type IN (
|
||||
'вело', 'ходьба', 'бег', 'эллипс', 'гребля'
|
||||
)),
|
||||
purpose TEXT NOT NULL CHECK (purpose IN (
|
||||
'warmup', 'cooldown', 'separate'
|
||||
)),
|
||||
duration INTEGER,
|
||||
distance REAL,
|
||||
speed REAL,
|
||||
incline REAL,
|
||||
resistance INTEGER,
|
||||
notes TEXT DEFAULT '',
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
|
||||
FOREIGN KEY (workout_id) REFERENCES workouts(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX idx_cardio_workout ON cardio(workout_id);
|
||||
CREATE INDEX idx_cardio_purpose ON cardio(purpose);
|
||||
|
||||
-- ============================================================
|
||||
-- 9. СПРАВОЧНИК ТИПОВ ЗАМЕРОВ ТЕЛА
|
||||
-- ============================================================
|
||||
CREATE TABLE metric_types (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE,
|
||||
name TEXT NOT NULL UNIQUE, -- "Вес", "Грудь", "Бицепс", "Предплечье"...
|
||||
unit TEXT NOT NULL DEFAULT 'см', -- единица измерения
|
||||
category TEXT DEFAULT 'body', -- для группировки: body, strength, etc.
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- 10. ЗАМЕРЫ ТЕЛА (факт замера)
|
||||
-- ============================================================
|
||||
CREATE TABLE body_metrics (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE,
|
||||
client_id INTEGER, -- FK на clients
|
||||
metric_date TEXT NOT NULL, -- ISO8601
|
||||
notes TEXT DEFAULT '',
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
|
||||
FOREIGN KEY (client_id) REFERENCES clients(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_body_metrics_client ON body_metrics(client_id);
|
||||
CREATE INDEX idx_body_metrics_date ON body_metrics(metric_date);
|
||||
|
||||
-- ============================================================
|
||||
-- 11. ЗНАЧЕНИЯ ЗАМЕРОВ (нормализованно)
|
||||
-- ============================================================
|
||||
CREATE TABLE body_metric_values (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
body_metric_id INTEGER NOT NULL,
|
||||
metric_type_id INTEGER NOT NULL,
|
||||
value REAL NOT NULL,
|
||||
|
||||
FOREIGN KEY (body_metric_id) REFERENCES body_metrics(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (metric_type_id) REFERENCES metric_types(id) ON DELETE CASCADE,
|
||||
|
||||
UNIQUE (body_metric_id, metric_type_id) -- один тип замера — одно значение в замере
|
||||
);
|
||||
|
||||
CREATE INDEX idx_bmv_metric ON body_metric_values(body_metric_id);
|
||||
CREATE INDEX idx_bmv_type ON body_metric_values(metric_type_id);
|
||||
|
||||
-- ============================================================
|
||||
-- 12. ЛОГ СИНХРОНИЗАЦИИ
|
||||
-- ============================================================
|
||||
CREATE TABLE sync_log (
|
||||
device_id TEXT PRIMARY KEY,
|
||||
last_sync TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
||||
);
|
||||
@@ -0,0 +1,89 @@
|
||||
-- ============================================================
|
||||
-- Тестовые данные v2
|
||||
-- ============================================================
|
||||
|
||||
-- Клиенты
|
||||
INSERT INTO clients (sync_id, full_name, birth_date, goal) VALUES
|
||||
('cl-001', 'Иванов Иван Иванович', '1990-05-15', 'Набор мышечной массы'),
|
||||
('cl-002', 'Петрова Анна Сергеевна', '1995-11-22', 'Снижение веса, тонус');
|
||||
|
||||
-- Типы тренировок
|
||||
INSERT INTO workout_types (sync_id, name, sort_order) VALUES
|
||||
('wt-001', 'грудь-руки', 1),
|
||||
('wt-002', 'ноги', 2),
|
||||
('wt-003', 'спина-плечи', 3),
|
||||
('wt-004', 'круговая', 4),
|
||||
('wt-005', 'силовая', 5),
|
||||
('wt-006', 'многоповторная', 6);
|
||||
|
||||
-- Типы замеров
|
||||
INSERT INTO metric_types (sync_id, name, unit, category, sort_order) VALUES
|
||||
('mt-001', 'Вес', 'кг', 'body', 1),
|
||||
('mt-002', 'Грудь', 'см', 'body', 2),
|
||||
('mt-003', 'Талия', 'см', 'body', 3),
|
||||
('mt-004', 'Бёдра', 'см', 'body', 4),
|
||||
('mt-005', 'Бицепс', 'см', 'body', 5),
|
||||
('mt-006', 'Предплечье', 'см', 'body', 6),
|
||||
('mt-007', 'Бедро', 'см', 'body', 7),
|
||||
('mt-008', 'Голень', 'см', 'body', 8),
|
||||
('mt-009', 'Шея', 'см', 'body', 9);
|
||||
|
||||
-- Упражнения (с привязкой к типам тренировок)
|
||||
INSERT INTO exercises (sync_id, workout_type_id, name) VALUES
|
||||
('ex-001', 1, 'Жим лёжа'), -- грудь-руки
|
||||
('ex-002', 3, 'Горизонтальная тяга'), -- спина-плечи
|
||||
('ex-003', 2, 'Приседания'), -- ноги
|
||||
('ex-004', 3, 'Становая тяга'); -- спина-плечи
|
||||
|
||||
-- Тренировка клиента Иванова
|
||||
INSERT INTO workouts (sync_id, client_id, workout_type_id, start_time, end_time, notes, synced) VALUES
|
||||
('w-001', 1, 3, '2026-09-24T18:00:00Z', '2026-09-24T19:30:00Z', 'Хорошая тренировка', 1);
|
||||
|
||||
-- Упражнения в тренировке
|
||||
INSERT INTO workout_exercises (sync_id, workout_id, exercise_id, exercise_name, sort_order) VALUES
|
||||
('we-001', 1, 2, 'Горизонтальная тяга', 1),
|
||||
('we-002', 1, NULL, 'Тяга верхнего блока', 2);
|
||||
|
||||
-- Обычные подходы
|
||||
INSERT INTO sets (sync_id, workout_exercise_id, is_dropset, weight, reps, rating, sort_order, timestamp) VALUES
|
||||
('s-001', 1, 0, 15.0, 12, 3, 1, '2026-09-24T18:10:00Z'),
|
||||
('s-002', 1, 0, 20.0, 12, 4, 2, '2026-09-24T18:15:00Z');
|
||||
|
||||
-- Дроп-сет
|
||||
INSERT INTO sets (sync_id, workout_exercise_id, is_dropset, weight, reps, rating, sort_order, timestamp) VALUES
|
||||
('s-003', 1, 1, NULL, NULL, 5, 3, '2026-09-24T18:20:00Z');
|
||||
|
||||
INSERT INTO dropset_items (set_id, weight, reps, sort_order) VALUES
|
||||
(3, 25.0, 8, 1),
|
||||
(3, 20.0, 10, 2),
|
||||
(3, 15.0, 12, 3);
|
||||
|
||||
-- Кардио
|
||||
INSERT INTO cardio (sync_id, workout_id, cardio_type, purpose, duration, speed, sort_order) VALUES
|
||||
('c-001', 1, 'вело', 'warmup', 10, 20.0, 1),
|
||||
('c-002', 1, 'ходьба', 'cooldown', 15, 6.0, 2);
|
||||
|
||||
-- Замеры тела клиента Иванова (с разными типами)
|
||||
INSERT INTO body_metrics (sync_id, client_id, metric_date) VALUES
|
||||
('bm-001', 1, '2026-09-24T08:00:00Z');
|
||||
|
||||
INSERT INTO body_metric_values (body_metric_id, metric_type_id, value) VALUES
|
||||
(1, 1, 78.5), -- Вес
|
||||
(1, 2, 102), -- Грудь
|
||||
(1, 3, 84), -- Талия
|
||||
(1, 5, 36), -- Бицепс
|
||||
(1, 6, 29); -- Предплечье
|
||||
|
||||
-- Второй замер через неделю (добавили новые типы)
|
||||
INSERT INTO body_metrics (sync_id, client_id, metric_date) VALUES
|
||||
('bm-002', 1, '2026-10-01T08:00:00Z');
|
||||
|
||||
INSERT INTO body_metric_values (body_metric_id, metric_type_id, value) VALUES
|
||||
(2, 1, 79.0), -- Вес
|
||||
(2, 2, 103), -- Грудь
|
||||
(2, 3, 83), -- Талия
|
||||
(2, 5, 36.5), -- Бицепс
|
||||
(2, 6, 29.5), -- Предплечье
|
||||
(2, 7, 58), -- Бедро (новый тип!)
|
||||
(2, 8, 38); -- Голень (новый тип!)
|
||||
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
-- ============================================================
|
||||
-- Проверочные запросы v2
|
||||
-- ============================================================
|
||||
|
||||
-- 1. Все тренировки клиента с типом тренировки
|
||||
SELECT
|
||||
c.full_name,
|
||||
w.start_time,
|
||||
wt.name AS workout_type,
|
||||
w.notes,
|
||||
CASE WHEN w.end_time IS NULL THEN '🔥 Активная' ELSE '✅ Завершена' END AS status
|
||||
FROM workouts w
|
||||
JOIN clients c ON c.id = w.client_id
|
||||
LEFT JOIN workout_types wt ON wt.id = w.workout_type_id
|
||||
ORDER BY w.start_time DESC;
|
||||
|
||||
-- 2. Полная тренировка с дроп-сетами
|
||||
SELECT
|
||||
w.start_time,
|
||||
wt.name AS workout_type,
|
||||
we.exercise_name,
|
||||
CASE
|
||||
WHEN s.is_dropset = 0 THEN printf('%s кг × %s', s.weight, s.reps)
|
||||
ELSE '🔥 DROPSET'
|
||||
END AS set_info,
|
||||
s.rating
|
||||
FROM workouts w
|
||||
LEFT JOIN workout_types wt ON wt.id = w.workout_type_id
|
||||
JOIN workout_exercises we ON we.workout_id = w.id
|
||||
JOIN sets s ON s.workout_exercise_id = we.id
|
||||
WHERE w.id = 1
|
||||
ORDER BY we.sort_order, s.sort_order;
|
||||
|
||||
-- 3. Элементы дроп-сета
|
||||
SELECT
|
||||
s.id AS set_id,
|
||||
di.sort_order,
|
||||
di.weight,
|
||||
di.reps
|
||||
FROM sets s
|
||||
JOIN dropset_items di ON di.set_id = s.id
|
||||
WHERE s.is_dropset = 1
|
||||
ORDER BY s.id, di.sort_order;
|
||||
|
||||
-- 4. История упражнения (для подсказок)
|
||||
SELECT
|
||||
w.start_time,
|
||||
s.weight,
|
||||
s.reps,
|
||||
s.is_dropset
|
||||
FROM workout_exercises we
|
||||
JOIN sets s ON s.workout_exercise_id = we.id
|
||||
JOIN workouts w ON w.id = we.workout_id
|
||||
WHERE we.exercise_name = 'Горизонтальная тяга'
|
||||
AND w.end_time IS NOT NULL
|
||||
ORDER BY w.start_time DESC
|
||||
LIMIT 10;
|
||||
|
||||
-- 5. Динамика замеров клиента (для дашборда)
|
||||
SELECT
|
||||
bm.metric_date,
|
||||
mt.name AS metric_name,
|
||||
mt.unit,
|
||||
bmv.value
|
||||
FROM body_metrics bm
|
||||
JOIN body_metric_values bmv ON bmv.body_metric_id = bm.id
|
||||
JOIN metric_types mt ON mt.id = bmv.metric_type_id
|
||||
WHERE bm.client_id = 1
|
||||
ORDER BY bm.metric_date DESC, mt.sort_order;
|
||||
|
||||
-- 6. Динамика конкретного замера (например, бицепс)
|
||||
SELECT
|
||||
date(bm.metric_date) AS day,
|
||||
bmv.value
|
||||
FROM body_metrics bm
|
||||
JOIN body_metric_values bmv ON bmv.body_metric_id = bm.id
|
||||
JOIN metric_types mt ON mt.id = bmv.metric_type_id
|
||||
WHERE bm.client_id = 1
|
||||
AND mt.name = 'Бицепс'
|
||||
ORDER BY bm.metric_date DESC;
|
||||
|
||||
-- 7. Статистика по клиентам (для тренера)
|
||||
SELECT
|
||||
c.full_name,
|
||||
c.goal,
|
||||
COUNT(DISTINCT w.id) AS total_workouts,
|
||||
SUM(CASE WHEN w.end_time IS NOT NULL THEN 1 ELSE 0 END) AS completed,
|
||||
MAX(w.start_time) AS last_workout
|
||||
FROM clients c
|
||||
LEFT JOIN workouts w ON w.client_id = c.id
|
||||
GROUP BY c.id
|
||||
ORDER BY last_workout DESC;
|
||||
|
||||
-- 8. Тренировки клиента за последнюю неделю
|
||||
SELECT
|
||||
w.start_time,
|
||||
wt.name AS workout_type,
|
||||
COUNT(DISTINCT we.id) AS exercises_count,
|
||||
SUM(CASE WHEN s.is_dropset = 0 THEN 1 ELSE (SELECT COUNT(*) FROM dropset_items WHERE set_id = s.id) END) AS total_sets
|
||||
FROM workouts w
|
||||
LEFT JOIN workout_types wt ON wt.id = w.workout_type_id
|
||||
LEFT JOIN workout_exercises we ON we.workout_id = w.id
|
||||
LEFT JOIN sets s ON s.workout_exercise_id = we.id
|
||||
WHERE w.client_id = 1
|
||||
AND w.start_time >= date('now', '-7 days')
|
||||
GROUP BY w.id
|
||||
ORDER BY w.start_time DESC;
|
||||
|
||||
-- 9. Все упражнения с их типами тренировок
|
||||
SELECT
|
||||
e.name,
|
||||
wt.name AS workout_type
|
||||
FROM exercises e
|
||||
LEFT JOIN workout_types wt ON wt.id = e.workout_type_id
|
||||
ORDER BY wt.sort_order, e.name;
|
||||
|
||||
-- 10. Все доступные типы замеров
|
||||
SELECT
|
||||
name,
|
||||
unit,
|
||||
category
|
||||
FROM metric_types
|
||||
ORDER BY sort_order;
|
||||
Reference in New Issue
Block a user