На самом деле я сталкиваюсь с серьезной проблемой, связанной с запросом 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);