SQL-запрос, который фильтрует результаты по тегам из группы тегов, используя меньшее количество нежелательных тегов в этой группе тегов - PullRequest
0 голосов
/ 03 октября 2019

На самом деле я сталкиваюсь с серьезной проблемой, связанной с запросом SQL, пытающимся отфильтровать, чтобы получить лучший элемент, на который я нацеливаюсь при многих условиях.

У меня есть 3 таблицы

  • Таблица Models, содержащая следующие столбцы: id (int pk), model (varbinary), fk_model_gen (int)
  • Таблица TypeAssociations, содержащая следующие столбцы: idModel (int fk), idType (int fk)
  • Тип таблицы, содержащий следующие столбцы: id (int pk), name (varchar)
  • Тип таблицы содержит разные типы с именем
  • Таблица типов TypeAssociations позволяет вамсвязать тип с моделью (модель может иметь неопределенное количество типов)
  • Таблица моделей содержит модели, которые я хочу выбирать в соответствии с типами.

Моя цель - иметь возможность выбирать модель из диапазона типов, не имея других типов, или, если она не существует в базе, по крайней мере, иметь ее минимум. Например:

, если у меня есть типы: A, B, C, D, E, F

Я хочу иметь возможность выбрать модель относительно типов A, B, CУ меня в базе 4 модели

Модели:

id      model         fk_model_gen
1   binaryContent          2
2   binaryContent          2
3   binaryContent          3
4   binaryContent          4

Тип Ассоциации:

idModel  idType
   3       1 
   3       2 
   3       3
   1       1
   1       2
   1       3
   1       4
   2       1
   2       2
   4       1
   4       2
   4       3
   4       4
   4       5

Тип:

id    name
 1      A
 2      B
 3      C
 4      D
 5      E
 6      F

Условияисследования следующие:

  • Я хочу получить модель, содержащую наибольшее количество типов, например, я хочу в идеале модель, у которой есть обе категории ABC, если у меня нетя беру один с двумя из них ...

  • Когда у меня много моделей с обеими этими 3 категориями, я хочу модель, у которой нет других категорий или у которой есть минимальное количество другихкатегории

    В моем запросе должна быть возвращена только одна модель

. В указанном выше случае я хотел бы получить только модель с идентификатором 3.

Я на самом деле пробовал некоторые вещи, такие как получение моделей с максимумом этих категорий и минимумом других категорий:

/* MAX */
SELECT DISTINCT TypeAssociations.IdModel FROM Models 
INNER JOIN TypeAssociations ON Models.id = TypeAssociations.IdModel
INNER JOIN Type ON TypeAssociations.IdType = Type.Id AND Type.name IN ('A', 'B', 'C')
WHERE
Models.fk_model_gen = 2
ORDER BY TypeAssociations.IdModel DESC;

/* MIN */
SELECT DISTINCT TypeAssociations.IdModel FROM Models 
INNER JOIN TypeAssociations ON Models.id = TypeAssociations.IdModel
INNER JOIN Type ON TypeAssociations.IdType = Type.Id AND Type.name NOT IN ('A', 'B', 'C')
WHERE
Models.fk_model_gen = 2
ORDER BY TypeAssociations.IdModel ASC;

Whв то время, когда меня искали, нужно было объединить результат этих двух запросов, чтобы получить верхний элемент, но после этого я увидел, что он не включает случай модели, которая содержит в точности категории, упомянутые в IN или NOT IN.

Я пытался объединить три условия без успеха:

SELECT Models.id FROM Models 
INNER JOIN TypeAssociations ON Models.id = TypeAssociations.IdModel
INNER JOIN Type ON TypeAssociations.IdType = Type.Id
WHERE
Models.fk_model_gen = 2 AND
TypeAssociations.IdModel IN (
    SELECT IdModel FROM Models 
    INNER JOIN TypeAssociations ON Models.id = TypeAssociations.IdModel
    INNER JOIN Tags ON TypeAssociations.IdType = Type.Id AND Type.name IN ('A', 'B', 'C')
    WHERE
        Models.fk_classifier_id = 2
) AND
TypeAssociations.IdModel NOT IN (
    SELECT IdModel FROM Models 
    INNER JOIN TypeAssociations ON Models.id = TypeAssociations.IdModel
    INNER JOIN Type ON TypeAssociations.IdTag = Type.Id AND Type.name NOT IN ('A', 'B', 'C')
    WHERE
    Models.fk_model_gen = 2
) OR
TypeAssociations.IdModel IN (SELECT IdModel FROM Models 
    INNER JOIN TypeAssociations ON Models.id = TypeAssociations.IdModel
    INNER JOIN Type ON TypeAssociations.IdTag = Type.Id AND Type.name NOT IN ('A', 'B', 'C')
    WHERE
    Models.fk_model_gen = 2)
GROUP BY Models.id
ORDER BY MAX(TypeAssociations.IdModel);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...