Home > Net >  linq query to get possible combinations
linq query to get possible combinations

Time:03-18

I have table1 like

funid reasonid
1 1
1 2
2 1
2 3

and users table(users will repeat) like below

userid reasonid
10 1
10 2
11 1
12 3
13 1
13 3

how to write a query to get the users satisfying table 1 combination {1,2} and {1,3}, so as per the above data userid 10 and 13 should be the output because user should have combination of {1,2} OR {1,3}

Thanks

CodePudding user response:

I would first count the number or reasons per funid in table1 , and then compare that with the count (distinct reasonid) obtained with a join between table1 and users grouped by userid and funid. If the counts are equal, then that user satisfies the condition.

Something like:

SELECT B.userid, B.funid
FROM (
    SELECT funid, reasonCount = COUNT(*)
    FROM table1
    GROUP BY funid
) A
JOIN (
    SELECT U.userid, T.funid, reasonCount = COUNT(DISTINCT U.reasonid)
    FROM users U
    JOIN table1 T ON T.reasonid = U.reasonid
    GROUP BY U.userid, T.funid
) B ON B.funid = A.funId AND B.reasonCount = A.reasonCount
ORDER BY B.userid, B.funid

The COUNT(DISTINCT ...) is only needed if it is possible that a user could reference the same reason more than once. You can drop the funid and add distinct to the final result to eliminate dups caused by users who satisfy more than one rule set (such as a user referencing reasons 1, 2, and 3).

Results:

userid funid
10 1
13 2

See this db<>fiddle for a demo.

CodePudding user response:

(int funid, int reasonid)[] t1 = new[] { (1, 1), (1, 2), (2, 1), (2, 3) };
(int userid, int reasonid)[] t2 = new[] { (10, 1), (10, 2), (11, 1), (12, 3), (13, 1), (13, 3) };
var rules = from x in t1 group x by x.funid into g 
            select (rule: g.Key, reasons: g.Select(x => x.reasonid));
var users = from x in t2 group x by x.userid into g 
            select (user: g.Key, reasons: g.Select(x => x.reasonid));
var result = from r in rules from u in users 
             where r.reasons.SequenceEqual(u.reasons) 
             select (r.rule, u.user);

result is { (1, 10), (2, 13) }

  • Related