简体   繁体   中英

mysql NOT IN query

I am trying to produce a list of user that have access to particular locations. The table in my database that records locations users have access to is backwards in my opinion. It list the location the users can not access. I have tried not in several different ways without any luck. The query just returns a blank results set. I've tried find something on here to help me and googled it but this has not helped...I always get blank results screen(nothing returned). I think the issue lies with the USER_LOCATION_EXCLUSION having several entries for each USER_ID for each corresponding location. I did not create this table structure but inherited it.

Scenario

Tables                  Columns
====================================================
APP_USER                USER_ID, USER_NAME    
LOCATION                LOCATION_ID, LOCATION_NAME    
USER_LOCATION_EXCLUSION USER_ID, LOCATION_ID

APP_USER and LOCATION tables both have IDs that are unique. These IDs are both used in USER_LOCATION_EXCLUSION (list locations users can not access) and can be used many times in this table according to the users access. I would like to produce report that has the USER_NAME and LOCATION_NAME they have access to.

What it sounds like you want is a Cartesian result LESS the exclusions... ie: for each user, assume giving them EVERY location access, then find out what they are excluded from...

select
      PreQuery.User_ID,
      PreQuery.User_Name,
      PreQuery.Location_Name
   from
      ( select
               AU.User_ID,
               AU.User_Name,
               L.Location_ID,
               L.Location_Name
            from
               App_User AU,
               Location L ) PreQuery
         LEFT JOIN USER_LOCATION_EXCLUSION ULE
             on PreQuery.User_ID = ULE.User_ID
             AND PreQuery.LOCATION_ID = ULE.LOCATION_ID
       where
          ULE.Location_ID = NULL

By doing a LEFT JOIN to the exclusion table, every record will ATTEMPT to be joined to the exclusion list... So, when it DOES find a match, that location ID will exist... when it does NOT exist, it will be null (satisfying your NOT Excluded from)

This also eliminates sub-select WHERE clause tested for every user / location

I would use something like this. To obtain all combinations of locations-users you could use a Select query with no joins:

Select *
From Location, App_User

but from here you have to exclude combinations of locations-users that are included in user_location_list table. This can solve your problem:

Select
  Location.*,
  App_User.*
From App_USer, Location
Where
  Not Exists (select * from user_location_exclusion
              where user_location_exclusion.user_id=app_user.user_id
              and user_location_exclusion.location_id=location.location_id)

This shows every location for every user that has not been excluded.

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