Reputation: 505
I have the following table, which describes permissions a specific user has on specific objects:
+------+-----------+----------+-----------+------------+------------+
| type | object_id | can_read | can_write | can_delete | can_create |
+------+-----------+----------+-----------+------------+------------+
| 0 | 1 | 1 | 0 | 0 | 1 |
| 0 | 1 | 1 | 1 | 0 | 0 |
| 0 | 2 | 1 | 0 | 0 | 0 |
| 1 | 1 | 1 | 1 | 1 | 0 |
+------+-----------+----------+-----------+------------+------------+
type and object_id is integers.
type is the object type. There exist different types of objects sharing the same object_id, but should be treated as different objects due to different "type".
can_read, can_write, can_delete, can_create is booleans, which describe what the current selected user can do on the (type, object_id) tuple.
This table is the output of a couple of UNION's, which both fetches rights that an individual user has on object_id, and rights that an specific "Group" as on object_id, where the individual user is member, which is then repeated for every object type.
Now to the problem. I now want to return rows that are distinct over type and object_id. For any duplicate records, the boolean values should be an logical "OR" over every row.
In this case, the above example table should be returned as:
+------+-----------+----------+-----------+------------+------------+
| type | object_id | can_read | can_write | can_delete | can_create |
+------+-----------+----------+-----------+------------+------------+
| 0 | 1 | 1 | 1 | 0 | 1 |
| 0 | 2 | 1 | 0 | 0 | 0 |
| 1 | 1 | 1 | 1 | 1 | 0 |
+------+-----------+----------+-----------+------------+------------+
In this case, since the selected user, has rights can_read=true, can_write=false, can_delete=false, can_create=true coming from a individual user right, on type=0,object_id=1. And then the same user has rights can_read=true, can_write=true, can_delete=false, can_create=false coming from a Group membership on type=0,object_id=1.
The effective rights is thus can_read=true, can_write=true, can_delete=false, can_create=true.
Upvotes: 0
Views: 778
Reputation: 133370
could be you need an aggreagtion function for merge the values in this case max valeue for each type object_id
select type, object_id
, max(can_read) can_read
, max(can_write) can_write
, max(can_delete) can_delete
, max(can_create) can_create
from my_table
group by type, object_id
and for an union
select type, object_id
, max(can_read) can_read
, max(can_write) can_write
, max(can_delete) can_delete
, max(can_create) can_create
from (
select type, object_id, can_read, can_write, can_delete, can_create
from table1
union
select type, object_id, can_read, can_write, can_delete, can_create
from table2
) t
group by type, object_id
Upvotes: 1
Reputation: 2480
To get 1 if 1 line is 1 and 0 if both, you need to use MAX() function :
SELECT type, object_id,
MAX(can_read),
MAX(can_write),
MAX(can_delete),
MAX(can_create)
FROM myTable
GROUP BY type, object_id
Upvotes: 0