Query Salesforce users and their permission sets (SOQL) - permissions

i'm trying to run an SOQL query on salesforce to get all users and their permission set id.
it is important the list return will be by user not by permission sets, meaning if i have 1000 users i will get back 1000 records and for each record the user attributes like email etc + permission sets list of Id's assign to him
SELECT+id,PermissionSet.id+FROM+User i tried finding the relationship field name but i'm not so familiar wtih salesforce, please assist

https://developer.salesforce.com/docs/atlas.en-us.238.0.object_reference.meta/object_reference/sforce_api_erd_profile_permissions.htm
The table you're looking for is PermissionSetAssignment
Top-down:
select id, email,
(select permissionsetid
from permissionsetassignments
where permissionset.isownedbyprofile = false)
from user
or bottom-up
select assigneeid, assignee.email, permissionsetid
from permissionsetassignment
where permissionset.isownedbyprofile = false
order by assigneeid

Related

Oracle query - How to check if a user is the only one assigned to a project

I am trying to determine if a user is assigned to any project with a specific role (ProjMemberTypeID) and if so, if s/he is the only one.
There is "projMember" table with Project ID, User ID and Project Member Type ID. I need to know if there are any project IDs where this user is the only one with member type id of 1.
Is it also possible to get some project info (like name, ...) joining the requested query with "Project" table, based on Project ID?
I tried this but it only gives me how many users are assigned to projects and if I filter by user ID I get how many projects user is assigned to but don't know how to check if s/he is the only one.
select count(userid), projectid
from projmember
where projmembertypeid = 1 -- and userid=73
group by projectid
order by projectid;
You can use a having clause:
select projectid
from projmember
where projmembertypeid = 1
group by projectid
having min(userid) = 73 and max(userid) = min(userid)
order by projectid;
The query filters on the relevant member type, then aggregates by project; all that is left to do is ensure that the given user was found, and no other.

How to display different interactive grid queries, depending on user privileges

I use Master-Detail page. I want to display whole table only for user who is an administrator. For the user who isn't the administrator, I want to display sql query which will be restrict MD view.
I tried to create another one master detail on same page which is visible only for users without Administrator role. And first MD is not visible for them.(I used Server-side Condition) Is there exist some other way to display different query, depending on user role.
I hope I explained the problem clearly. Thanks in advance
Have a look at the package APEX_ACL, you can use the related views in your where clause.
Example:admins see all rows, other users only see the row for KING
SELECT *
FROM emp
WHERE
-- user is admin ?
( EXISTS ( SELECT 1
FROM apex_appl_acl_user_roles
WHERE application_id = :APP_ID AND
user_name = :APP_USER AND
role_static_id = 'ADMINISTRATOR'
) ) OR
-- user is no admin
( ename = 'KING' );

Setting a column value for only one user depending on results

I'm currently playing around with SQL and trying to find the best way to accomplish this:
I currently have a user table that has a user_id, organisation_id, registered_datetime. There are
a number of users in this table with different organisations. There may be 3 different users in
1 organisation, or 1 in 1 organisation, etc.
I have added a new column called admin_user and I am trying to string up an SQL statement together
to update the admin user column. There can only be one admin user per organisation, and I want
the user who registered the earliest for that organisation to be the admin.
I could do this manually but it would take time if I had a lot of users. What would be the best
way to accomplish this?
EDIT:
So I have a number of users like this with the columns. The ones highlighted are the users that has registered the earliest. I want to be able to set those users as an admin user. The only admin user within their organisation and set the rest to 0. 1 (Admin) 0 (Not Admin)
This SQL query will mark users which registered_datetime are lowest in its organisation_id as admin.
UPDATE users SET admin_user = 1
WHERE user_id IN (
SELECT u.user_id FROM users u
WHERE u.registered_datetime IS NOT NULL AND NOT EXISTS(
SELECT 1 FROM users iu
WHERE iu.organisation_id = u.organisation_id AND iu.registered_datetime < u.registered_datetime
)
)
You might want to update all users to admin_user = 0 before this code, so all your users will have their values set.
One caveat here, if two users in one organisation were registered in exact same time, then both of them will be marked as administrators.
Update
I have added u.registered_datetime IS NOT NULL into the WHERE clause to filter out users with NULL in registered_datetime.
MSSQL
In MsSql server I usually solve this problem a in another way, by using ROW_NUMBER():
WITH base AS (
SELECT user_id, ROW_NUMBER() OVER ( PARTITION BY organisation_id ORDER BY registered_datetime ASC ) AS rn
FROM user
WHERE registered_datetime IS NOT NULL
)
UPDATE user SET is_admin = 1
WHERE user_id IN (
SELECT base.user_id FROM base WHERE rn = 1
)
This is too long for a comment.
You are describing three different tables:
Users
Organizations
UserOrganizations
The last has one row per user and per organization. This provides the mapping between the two. This can be called a "mapping" table, "junction" table, or "association" table.
How you implement one admin per organization depends on the database you are using.
You do not need the admin_user column. You need a column isadmin.
When a user is registered, if he is the first in the organization, then the isadmin column has the value 1, otherwise 0
Also, you can use the AAA query to find the administrator
SELECT `table`.`user_id`, MIN(`table`.`registered_datetime`) WHERE `organisation_id`=...

Not able to return a field from a child of a parent in SOQL

I have tested the following query which is successful but when apply the query to my custom object it fails. i need to find out what is causing the issue.
SELECT Id, Account.Name FROM Contacts WHERE AccountId in (SELECT Id FROM Account)
Background: There are two entities: Customers and Visits, there can be many visits for any customer. I have created a custom object Customer_Visits__c with several fields. It has a lookup field called Customer__c which looks up to Account (sObject) and stores the Account Id field. The relationship name is CustomerVisitsAccounts. I want to be able to return the customer name field (Account.Name) in the SOQL query, i.e., for each visit record show the name of the customer.
It get success with:
SELECT Id, Name FROM Customer_Visits_c WHERE Customer_c in (SELECT Id FROM Account)
Here is the SOQL string I get fails with:
SELECT Id, Name, CustomerVisitsAccounts__r.Name FROM Customer_Visits_c WHERE Customer_c in (SELECT Id FROM Account)
Here is the error message I get:
ERROR at Row:1:Column:18
Didn't understand relationship 'CustomerVisitsAccounts_r' in field path. If you are attempting to use a custom relationship, be sure to append the '_r' after the custom relationship name. Please reference your WSDL or the describe call for the appropriate names.

how can I do this select query

I have in my SQL Server, a table called FavoriteUsers with a list of users and a table called Users with all users.
In my ASPX page, I have a TextBox where my user can put the ID of an User to list in my GridView.
How it works
By default, I fill my GridView with all data of my FavoriteUsers table, and if the user of my system put some user code in the textbox field and click on my button to find these users, I'll reload the GridView with the FavoriteUsers and the users that he put on TextBox field that come from the table Users.
How can I do this SELECT query ?
select * from FavoriteUsers
UNION
select * from Users
Where userid = 'TextBox.text'
Of course you can't use TextBox.text in there. But you only needed the query so you get the point.
NOTE: The UNION will leave out any records from Users that already exist in FavoriteUsers. So you won't have duplicates.
Get all favorite users plus the user whose username matches that entered into the textbox:
SELECT Users.*
FROM Users
LEFT JOIN FavoriteUsers ON Users.UserID = FavoriteUsers.UserID
WHERE (FavoriteUsers.UserID IS NOT NULL) OR (Users.Username = #Username)