#sql #sql-server #inner-join #having-clause #relational-division
#sql #sql-сервер #внутреннее соединение #наличие-предложение #реляционное разделение
Вопрос:
Для того, чтобы пользователь имел доступ к сущности, пользователь должен иметь необходимые классификации, настроенные для него. Классификации имеют несколько атрибутов разных типов атрибутов. Пользователи в равной степени имеют несколько атрибутов. Для того, чтобы пользователь соответствовал требованиям классификации, он должен иметь по крайней мере один атрибут каждого типа, применяемый к классификации.
Итак, из следующих данных
dbo.Classification
ClassificationID ClassificatinName
10 Class1
dbo.Attribute
AttributeID AttributeName AttributeTypeID
1 Type1 Attr1 1
2 Type1 Attr2 1
3 Type2 Attr1 2
4 Type2 Attr2 2
dbo.ClassificationAttribute
ClassificationID AttributeID
10 1
10 2
10 4
dbo.EntityClassification
EntityID ClassificationID
100 10
dbo.UserAttribute
UserID AttributeID
1000 1
1000 4
2000 2
2000 3
Идентификатор пользователя 1000 должен соответствовать требованиям для ClassificationID 10 и, следовательно, EntityId 100, поскольку у них есть по крайней мере один атрибут каждого типа, настроенный для этой классификации, но пользователь 200 не должен. Данные, которые я хочу в конечном итоге вернуть, будут:
UserID EntityID
1000 100
Как это можно сделать в SQL?
Комментарии:
1. «Как это лучше всего сделать в SQL?» Это слишком широкий вопрос. В чем заключается ваш конкретный вопрос? Что насчет того, что вы пробовали, не сработало, или почему вы считаете, что это не «лучше»? Что определяет «лучший»?
2. Вы забыли указать нам имена таблиц.
3. Извините, как это можно было сделать, лучше или иначе, это то, что я имел в виду.
Ответ №1:
Я понимаю это как проблему реляционного разделения. Вы можете обратиться к нему с помощью объединений и having
предложения для фильтрации:
select ec.entityid, ua.userid
from entityclassification ec
inner join attribute a1 on a1.attributeid = ec.attributeid
inner join attribute a2 on a2.attriubutetypeid = a1.attriubutetypeid
inner join userattribute ua on ua.attributeid = a2.attributeid
where ec.entityid = 100
group by ec.entityid, ua.userid
having count(distinct a2.attriubutetypeid) = (
select count(distinct a3.attriubutetypeid)
from entityclassification ec3
inner join attribute a3 on a3.attributeid = ec.attributeid
where ec3.entityid = 100
)
В основном это объединяет всех пользователей, чьи атрибуты имеют хотя бы один общий тип с целевой сущностью. Затем предложение having гарантирует, что все типы были сопоставлены.