简体   繁体   中英

Compare values across two tables grouped by another value SQL

In order for a user to have access to an entity a user must have the necessary Classifications that are configured against it. Classifications have multiple attributes of different attribute types. Users equally have multiple attributes. In order for the user to meet the requirements of the classification they must have at least one attribute of each type applied to the classification.

So from the following data

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

UserID 1000 should meet the requirements for ClassificationID 10 and hence EntityID 100 because they have at least one attribute of each type configured against that Classification, but User 200 should not. The data I want to ultimately return then is:

UserID      EntityID
1000        100

How can this be done in SQL?

I understand this as a relational divison problem. You can approach it with joins, and a having clause for filtering:

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
)

Basically this brings all users whose attributes have at least one type in common with the target entity. Then the having clause ensures that all types were matched.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM