简体   繁体   中英

Complicated Conditions in SQL Query

I am currently working on a very big project which involves many-to-many and one-to-many relationships... There are a few tables to work with and I can't figure out how to do what I want. Here is my first table (Objects Table) :

+-----------+------+-------+
| Object ID | Name | Value |
+-----------+------+-------+   The Object ID is a foreign Key to another table.
|     1     | Aaaa |   2   |   The Name is unique for each Object ID.
|     1     | Bbbb |   5   |
|     2     | Aaaa |   15  |
|     2     | Bbbb |   3   |
+-----------+------+-------+

My second table is the following (Users Table) :

+---------+------+-------+
| User ID | Name | Value |
+---------+------+-------+    The User ID is also a foreign Key, there are  
|    7    | Aaaa |  10   |    multiple rows with the same User ID. 
|    7    | Bbbb |   7   |
+---------+------+-------+

I have a third table showing the relationship between the other tables

+---------+-----------+
| User ID | Object ID |
+---------+-----------+ There are no identical rows in this table. 
|    7    |     1     |
+---------+-----------+

I am trying to find all the objects in the Objects Table that the user has. The user needs to have ALL the object names. And for each Name, the value of the User must be at least the value of the Object for that name.

For example here, the user has Aaaa with a value of 10 and Bbbb with a value of 7. So he has ALL of the names of the Object 1 and his values are greater than or equal to those values. Therefore he can have Object n° 1. For object 2, the User doesn't have enough of Aaaa, so he can't have the object 2.

I know how to get all of the rows of Objects Table where the User has the Name and a big enough value with Inner Joins :

SELECT Users.User ID, Objects.Object, Objects.Name ID FROM Objects
INNER JOIN Users
ON Objects.Name = Users.Name AND Objects.Value <= Users.Value

But the problem is that it would return the following :

+---------+-----------+------+
| User ID | Object ID | Name |
+---------+-----------+------+
|    7    |     1     | Aaaa |
|    7    |     1     | Bbbb |
|    7    |     2     | Bbbb |
+---------+-----------+------+

The problem is that I want to get rid of the last row here since the user doesn't have enough of Aaaa for Object 2.

Any help would be greatly appreciated ! Thanks

You could use a not exists clause to demand that none of the matching objects has a higher value than the user's value:

select  Users.User ID, Objects.Object, Objects.Name ID 
from    Objects o
join    Users u
on      o.Name = u.Name 
where   not exists
        (
        select  *
        from    Objects o2
        where   o2.Name = u.Name
                and o2.Value > u.Value
        )

Your description is a little confusing, because you have the same "Name" for the users and objects. I am assuming that the user name is different from the object name, and you wantto use the mapping table.

You should be able to do this with a join:

select u.userid, o.objectid, o.name
from UserObjects uo join
     Users u
     on uo.userid = u.userid join
     Objects o
     on uo.objectid = o.objectid
where u.value >= o.value

If the names in the object table and user table are really the same, then (1) you have a non-normalized database structure and (2) you don't need the user objects table. You might want to ask another question to see if we can come up with a better database structure for these tables.

If your goal is to populate the user objects table, then the query is even simpler:

select u.userid, o.objectid, o.name from Users u join Objects o on u.name= o.name where u.value >= o.value

You can create the table by having the following line before the insert:

insert into UserObjects(UserId, ObjectId, Name, Value)

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