开发者

How to filter for a specific set of values in SQL, and only that specific set?

开发者 https://www.devze.com 2023-02-07 05:36 出处:网络
I have a problem with an inherited database for which the person who originally set it up left little documentation.

I have a problem with an inherited database for which the person who originally set it up left little documentation.

I have a set of users, each with three potential occupations. When queried, it returns values like these:

USER_ID CAREER_ID   TITLE
1       44           Agricultural Engineer
1       136          Educational Psychologist
1       132          Clinical Psychologist
18      245          3D Designer
18      2            Accountant - Private Practice
18      1            Accountant - Industry and Commerce
19      245          3D Designer
19      2            Accountant - Private Practice
19      1            Accountant - Industry and Commerce
20      128          Advice Centre Worker
20      130          Careers Adviser
20      129          Care Assistant
21      1            Accountant - Industry and Commerce
21      245          3D Designer
21      2            Accountant - Private Practice
23      245          3D Designer
23      2            Accountant - Private Practice
23      1       开发者_JAVA技巧     Accountant - Industry and Commerce
29      245          3D Designer
29      2            Accountant - Private Practice
29      1            Accountant - Industry and Commerce
30      219          PC Games Tester
30      173          Bouncer
30      103          Stunt Person
32      245          3D Designer
27      2            Accountant - Private Practice
27      1            Accountant - Industry and Commerce
27      245          3D Designer
30      219          PC Games Tester
30      173          Bouncer
30      103          Stunt Person

As you can see, for some reason, careers 1, 2, and 245 are set as defaults. Now, I want to filter out the users that have that specific set of careers, but not all instances of them, as any user could have legitimately chosen one or two of the set.

I can live with filtering out the odd character who just might have actually chosen that particular set on purpose.

Hope someone can help. I'm sure the solution is rather simple, but I can't come up with it.


Select ...
From Occupations O
Where Not Exists    (
                    Select 1
                    From Occupations O1
                    Where O1.Career_Id In(1,2,245)
                        And O1.User_Id = O.User_Id
                    Group By O1.User_Id
                    Having Count(*) = 3
                    )

Another solution:

Select ...
From Occupations O
Where Exists    (
                Select 1
                From Occupations O1
                Where O1.Career_Id Not In(1,2,245)
                    And O1.User_Id = O.User_Id
                )

The catch with the above solution is that it will exclude those that only have fewer than all three default careers. I.e., it will exclude users that only have (1,2), (1,245), (2,245), (1), (2), (245). If they must have all three and only those three, then you need to modify this solution like so:

Select ...
From Occupations O
Where Exists    (
                Select 1
                From Occupations O1
                Where O1.Career_Id Not In(1,2,245)
                    And O1.User_Id = O.User_Id
                )
Or Exists   (
            Select 1
            From Occupations O2
            Where O2.User_Id = O.User_Id
            Having Count(*) < 3
            )


Assuming you have a user table, career table, and a mapping table (user_career_map), then this will get you what you are looking for:

SELECT user_id, career_id, title
FROM (
  SELECT distinct m.user_id, m.career_id, c.title
    , sum(case when m.career_id in (1, 2, 245) then 1 else 0 end) over (partition by     m.user_id) filter
  FROM user_career_map m inner join career c on m.career_id = c.career_id
) WHERE filter <> 3
ORDER BY user_id, career_id;


I think this should identify the users who have careers 1, 2 and 245 listed:

SELECT User_ID
  FROM Occupations
 WHERE Career_ID IN (1, 2, 245)
 GROUP BY Career_ID
HAVING COUNT(*) = 3

If you want the list of users who don't have that set of careers, then:

SELECT User_ID
  FROM Occupations
 WHERE User_ID NOT IN
       (SELECT User_ID
          FROM Occupations
         WHERE Career_ID IN (1, 2, 245)
         GROUP BY Career_ID
        HAVING COUNT(*) = 3)
0

精彩评论

暂无评论...
验证码 换一张
取 消