Форум программистов, компьютерный форум, киберфорум
PostgreSQL
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 25.02.2019
Сообщений: 4

Составление сложного запроса SQL

23.02.2021, 13:08. Показов 1166. Ответов 2

Студворк — интернет-сервис помощи студентам
Доброго времени суток, у меня есть следующая задача - реализовать сервис (как тут) по подбору образов (людей в определенной одежде). Входными данными выступают элементы одежды, а выходными - образы, в которых присутствуют эти элементы одежды.
Например, пользователь выбрал две вещи: Джинсы и Черное длинное пальто, а сервис должен найти такой образ, на котором есть эти элементы одежды.

Одежду я решил хранить в БД в виде дерева (используя ltree):
Кликните здесь для просмотра всего текста
1 Брюки
ᅠ1.1 Классические брюки
ᅠᅠ1.1.1 Черные классические брюки
ᅠᅠ1.1.2 Белые классические брюки
ᅠ1.2 Джинсы
ᅠᅠ1.2.1 Темные джинсы
ᅠᅠ1.2.2 Светлые джинсы
ᅠᅠ1.2.3 Джинсы с дырками
2 Пальто
ᅠ2.1 Длинное пальто
ᅠᅠ2.1.1 Черное длинное пальто
ᅠᅠ2.1.2 Коричневое длинное пальто
ᅠ2.2 Полупальто
ᅠᅠ2.2.1 Черное полупальто
ᅠᅠ2.2.2 Коричневое полупальто


Важное условие, что если пользователь выбрал Длинное пальто, то в результате также должны присутствовать все дочерние элементы (Черное длинное пальто и Коричневое длинное пальто)

Диаграмму таблиц прикрепил ниже:
• Таблица all_clothes хранит данные о всех возможных вещах.
• Таблица characters хранит данные о всех образах.
• Таблица clothes_on_characters хранит данные о том, в какую одежду одет каждый образ.

Собственно вопрос, как написать такой SQL запрос, чтобы он возвращал образы, в которых есть определенная одежда?
Я понимаю алгоритм, но не могу объединить это все в один запрос, так как мало знаком с SQL языком((( Был бы крайне благодарен за помощь
Кликните здесь для просмотра всего текста
1. По входным id одежды (например 5 и 11) достать parent_path и найти всех предков
SQL
1
SELECT * FROM all_clothes WHERE parent_path <@ '1' OR parent_path <@ '9.10.12';
2. После этого, достаем id образов из таблицы clothes_on_characters в которых есть id необходимой одежды (уже вместе с предками)
3. Достаем полную информацию об образах по их id


Код создания этих таблиц:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
CREATE EXTENSION ltree;
 
CREATE TABLE all_clothes (
    id INTEGER PRIMARY KEY,
    name TEXT,
    image_path VARCHAR(250),
    parent_id INTEGER REFERENCES all_clothes ON DELETE CASCADE,
    parent_path LTREE
);
 
CREATE TABLE characters (
    id INTEGER PRIMARY KEY,
    image_path VARCHAR(250),
    description TEXT,
    posted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
 
CREATE TABLE clothes_on_characters (
    id INTEGER PRIMARY KEY,
    character_id INTEGER REFERENCES characters ON DELETE CASCADE,
    clothes_id INTEGER REFERENCES all_clothes ON DELETE CASCADE
);
 
CREATE OR REPLACE FUNCTION update_all_clothes_parent_path() RETURNS TRIGGER AS $$
    DECLARE
        path ltree;
    BEGIN
        IF NEW.parent_id IS NULL THEN
            NEW.parent_path = NEW.id::text::ltree;
        ELSE
            SELECT parent_path FROM all_clothes WHERE id = NEW.parent_id INTO path;
            IF path IS NULL THEN
                RAISE EXCEPTION 'Invalid parent_id %', NEW.parent_id;
            END IF;
            NEW.parent_path = (path::text || '.' || NEW.id)::ltree;
        END IF;
        RETURN NEW;
    END;
$$ LANGUAGE plpgsql;
 
CREATE TRIGGER all_clothes_parent_path_tgr BEFORE INSERT OR UPDATE ON all_clothes
    FOR EACH ROW EXECUTE PROCEDURE update_all_clothes_parent_path();
Миниатюры
Составление сложного запроса SQL  
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
23.02.2021, 13:08
Ответы с готовыми решениями:

Составление сложного запроса
Всем доброго времени суток, помогите составить запрос, в котором будет выводится количество товаров, которые находятся на складе 1, 1-2,...

Составление сложного запроса на объединение таблиц
Всем привет! Есть таблицы из которых мы берем: banners.*, map_point.id, map_point.expiration_date, map_point_services.id_map_point,...

Составление сложного запроса, выборка по двум таблицам
в общем есть 2 таблицы, `template` и `template_design`, поля такие `template` = id,name. `template_design` = id, id_template,...

2
0 / 0 / 0
Регистрация: 25.02.2019
Сообщений: 4
23.02.2021, 18:52  [ТС]
Сделал такой вариант, не слишком ли плохо? Может быть его можно как то оптимизировать?

Вернет все образы, в которых есть Белые классические брюки (1.2.4) и Длинное пальто (9.10) одновременно:
SQL
1
2
3
SELECT * FROM characters WHERE id IN (SELECT character_id FROM clothes_on_characters WHERE clothes_id IN (SELECT id FROM all_clothes WHERE parent_path <@ '1.2.4'))
INTERSECT
SELECT * FROM characters WHERE id IN (SELECT character_id FROM clothes_on_characters WHERE clothes_id IN (SELECT id FROM all_clothes WHERE parent_path <@ '9.10'))
0
1263 / 977 / 384
Регистрация: 02.09.2012
Сообщений: 3,021
01.03.2021, 22:55
Не очень оптимальным выглядит запрос.
Без плана сказать невозможно, но выглядит как полный перебор двух таблиц два раза с последующим пересечением результата.

Почему бы не избавиться от многие-ко-многим и сразу в образах описывать массив идентификаторов элементов одежды, из которых эти образы состоят.
Тогда по известным LTREE из дерева элементов одежды можно собрать массив индентификаторов этих элементов одежды, принадлежащих поддеревьям известных LTREE.
Тогда массив, описывающий элементы одежды, должен входит в массив выбранных идентификаторов по известным LTREE - оператор <@.
Этот оператор поддается индексации (GIN индексы например), это должно значительнол помочь в ускорении поиска и упрощении запроса.

Пока код не пишу, просто предположение на обсуждение.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
01.03.2021, 22:55
Помогаю со студенческими работами здесь

Написание сложного запроса SQL
Задача такая: Оператор телефонной связи берет абонентскую плату 300р. и абонент может разговаривать 300 минут , но если абонент говорил...

Создание сложного SQL запроса
Всем привет нужно построить запрос SQL на объединение таким образом : --во всей базе (Access) нужно поиском выбрать строки,...

Составление SQL запроса
Имеются таблицы data и nips. Программе известен требуемый craftID (для примера возьмем 1). Нужно, чтобы из таблицы data были взяты значения...

Составление SQL запроса
ПОЖАЛУЙСТА ПОМОГИТЕ, есть база данных с таблицами Readers (SURNAME, NAME, CITY, AGE, DATE, UNIV_ID, STIPEND, Readers_ID), ...

Составление вложенного SQL запроса
С использованием вложенных запросов в операторе HAVING, найти количество читателей университетских библиотек (предварительно ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru