I am trying to execute a basic left join.
Structure of the tables are :
AGR_USERS : User (UNAME) - > AGR_NAME (Role) relationship - 1 to many
AGR_AGRS : Role (AGR_NAME) - > Child Role (CHILD_AGR) relationship - 1 to many
However the results are not accurate, since the query is not identifying the child roles(CHILD_AGR) present within the role (AGR_NAME) for users (UNAME).
Could you please help me to resolve the same. Below is the query which i am using.
SELECT
agr_users.UNAME,
agr_users.AGR_NAME,
AGR_AGRS.CHILD_AGR,
FROM AGR_USERS LEFT JOIN AGR_AGRS
ON AGR_AGRS.AGR_NAME=agr_users.AGR_NAME
**** MS-SQL server
Below is table data
Table 1 :AGR_AGRS ( role - child role table )
AGR_NAME CHILD_AGR
abc x
abc y
Table 2 : AGR_USERS ( User - role table)
UNAME AGR_NAME
nik abc
Expected result : ( User - role - child role )
UNAME AGR_NAME CHILD_AGR
nik abc x
nik abc y
This is a very straightforward query. The below should get you the full list:
select u.UNAME
,a.AGR_NAME
,a.CHILD_AGR
from AGR_USERS as u
left join AGR_AGRS as a
on u.AGR_NAME = a.AGR_NAME
If it does not, your environment must be different to how you have represented it within your question.
Related
I'm looking on how to provide permissions to users where I have a criteria table that has field/value pairs that match to different fields in my dataset.
Below is the permissions table.
Field
Value
Permissioned user
region
AMER
Kim
manager
Chris
Kim
division
Sales
Kim
region
EMEA
Julie
manager
Jim
Julie
This is the format of the data. Different fields represent the different fields above. There can be 8 or more different fields (eg region, business unit, dept head, etc) so I need an approach that scales beyond my dummy dataset.
EMP ID
region
division
manager
1
AMER
Marketing
Chris
2
AMER
Sales
Chris
3
EMEA
Sales
Chris
4
AMER
Sales
Jim
5
EMEA
Marketing
Jim
6
EMEA
Sales
Jim
The desired output applies the criteria across the different fields.
Permisioned User
EMP ID
region
division
manager
Kim
2
AMER
Sales
Chris
Julie
5
EMEA
Marketing
Jim
Julie
6
EMEA
Sales
Jim
I'm not really sure where to begin as I can't seem to get close. Intersect means that I always have the same fields applied in criteria but this isn't the case. Plus different users can have different number of criteria rules. Any help is really appreciated!
Thanks!
If the exhaustive list of fields that may be used to define permissions is fixed, then you can create a static query. If the list of fields is not fixed and only known at the run time, then you need a dynamic query.
Static list of permission fields / Static query
We cross join the permissions and data tables.
Then, we group the rows by "Permissioned user" and "EMP ID", and we only keep the grouped rows which all satisfy the (field, value) correspondance thanks to the aggregate function bool_and in the HAVING clause.
Finally we add all the columns of the data table and we order by "EMP ID" :
WITH list AS
(
SELECT p."Permissioned user"
, d."EMP ID"
FROM data AS d
CROSS JOIN permissions AS p
GROUP BY p."Permissioned user", d."EMP ID"
HAVING bool_and( CASE
WHEN p.field = 'region' THEN p.value = d.region
WHEN p.field = 'manager' THEN p.value = d.manager
WHEN p.field = 'division' THEN p.value = d.division
WHEN [...] -- insert here the rest of the fields list
ELSE FALSE
END
)
)
SELECT l."Permissioned user", d.*
FROM list AS l
INNER JOIN data AS d
ON d."EMP ID" = l."EMP ID"
ORDER BY d."EMP ID" ;
Variable list of permission fields / Dynamic query
The dynamic query allows to search data according to criteria which are known only at the run time. It must be embedded in a plpgsql function which will return the result of the dynamic query. For each "Permissioned user" in table permissions, the principle is to generate the where_clause string which matches with the WHERE clause of the query searching in table data. The "Permissioned user" and the where_clause are passed to the plpgsql function permissioned_user which contains the dynamic query and returns the list of "EMP ID" in table data :
CREATE OR REPLACE FUNCTION permissioned_user
( INOUT "Permissioned user" text
, IN where_clause text
, OUT "EMP ID" integer
)
RETURNS setof record LANGUAGE plpgsql IMMUTABLE AS
$$
BEGIN
RETURN QUERY EXECUTE E'
SELECT ' || quote_nullable("Permissioned user") || E'
, "EMP ID"
FROM data AS d
WHERE ' || where_clause ;
END ;
$$
Then the following query returns the expected result. First it generates the where_clause string associated to every "Permissioned user" in table permissions. Then it call the function permissioned_user(), gets the "EMP ID" list and joins with the rest of the data columns :
WITH list AS
( SELECT "Permissioned user"
, string_agg('d.' || quote_ident(Field) || E' = \'' || quote_nullable(Value) || E'\'', ' AND ') AS where_clause
FROM permissions
GROUP BY "Permissioned user"
)
SELECT a."Permissioned user", d.*
FROM list AS l
CROSS JOIN LATERAL permissioned_user(l."Permissioned user", l.where_clause) AS a
INNER JOIN data AS d
ON d."EMP ID" = a."EMP ID"
ORDER BY a."EMP ID"
Note that any Field value in table permissions which doesn't correspond to a column name in the data table will generate a SQL ERROR.
I'm having what I hope is a momentary lapse of reasoning. I have the following schema:
SELECT RoleName FROM aspnet_Roles; gives:
-----------------------------------------
Administrator
Backend
Business Manager
Content Editor
Employee
Salesperson
SELECT RoleName FROM aspnet_Roles r INNER JOIN admin_page_role apr ON r.RoleId = apr.RoleId WHERE apr.PageId = 4;
------------------------------------------
Administrator
Business Manager
Salesperson
What I want is the full list of the first query along with whether or not the role is assigned, like:
| RoleName | IsAssignedToPage
---------------------------------------
Administrator 1
Backend 0
Business Manager 1
Content Editor 0
Employee 0
Salesperson 1
I looked at How to write a MySQL query that returns a temporary column containing flags... which makes sense, but my admin_page_role table is a bridge table that can contain many page-role combinations.
Something like this:
SELECT RoleName, case when apr.roleid is null then 0 else 1 end as IsAssignedToPage
FROM aspnet_Roles r
LEFT JOIN admin_page_role apr ON r.RoleId = apr.RoleId and apr.PageId = 4
Have two tables : Applicant , Applies
//APPLICANT
A#
-------------
1
2
3
4
5
//APPLIES
A# POSITION
---------------------
1 GM
2 CEO
3 DIRECTOR
3 MANAGER
So i create the user like this:
CREATE USER TEST IDENTIFIED BY TESTING;
GRANT CREATE SESSION TO TEST;
Now i want grant select to TEST on table APPLICANT which have at least 1 record in APPLIES table using follow query:
SELECT a.A#,COUNT(a.A#) FROM APPLICANT a
INNER JOIN APPLIES ap ON a.A#=ap.A#
HAVING COUNT(a.A#)>0 GROUP BY a.A#;
how i grant to user TEST? with select clause condition
GRANT SELECT ON APPLICANT WHERE (SELECT.......) TO TEST;
Fail to work, errors come out.
I have a question about SQL Query. Let me do the example to illustration my issue:
I have two tables like this:
Roles Table
ID Role Role Description
1 Administrator Someone in administrator board
2 User Someone who has an account
3 Guess Someone who just view the website
Users Table
ID Username RoleID
1 trind08 1
2 trind09 1
3 trind10 1
4 kimchi 2
5 linhchi 2
6 thanh01 2
7 thanh02 3
8 kiemanh 3
9 liemanh 3
My issue is I want to view all roles and count the user who resolve to them.
Result table after running the query might look like this:
ID Role Role Description Cound of User
1 Administrator Someone in administrator board 3
2 User Someone who has an account 3
3 Guess Someone who just view the website 3
My first try to create a SQL Query like this:
select rol.*, usrCout as 'Count of User' from Roles rol
left join (select count(*) from Users where RoleID == rol.ID) usrCout;
But my query run unsuccessfully and I can't get the result I want. Please help me for this.
Thank you
SELECT
ID
,ROLE
,Role Description
,(SELECT COUNT(*) FROM Users where RoleID = rol.ID) AS UserCount
FROM Roles rol
Try this query
Select count(*) as 'Count of User', r.RoleID, Role, Role Description from role r, Users u where u.RoleId = r.Id group by r.RoleID,Role, Role Description;
Fiddle
Hope this helps
I'm new to SQL. I have a simple problem with getting the results from two different tables.
I have two tables in a database. The first table has a column with an id reference, which corresponds to rows in the second table. What SELECT do I need to perform to get a result such that the ids are repalced by all of the values in the second table. To visualize the tables I am discussing:
TABLE_USERS
===========
id username group
-- -------- -----
1 jim A
2 alice A
3 brandon B
TABLE_GROUPS
============
id groupname members
-- --------- -------
A designer 134
B photographer 39
DESIRED_SELECTION
=================
id username group
-- -------- -----
1 jim designer
2 alice designer
3 brandon photographer
Thanks!
You do, in fact, want to JOIN the two tables:
SELECT * FROM
TABLE_USERS LEFT JOIN TABLE_GROUPS
ON TABLE_USERS.group = TABLE_GROUPS.id
The trick of joining tables is to find the values that must match in the two tables, and use the on to tell SQL to match them. This table has a ID column to let you do that = you will join the table, ON, and then list the values that need to be equal.
If you do not want all of the columns in both tables, you can simply list only the columns you need in your final query. This means that instead of Select *, you list the columns you want. As shown below, if a column appears with the same name in both tables, you need to prepend the table name, so that SQL know which value you want.
SELECT TABLE_USERS.ID, Username, Groupname
FROM TABLE_USERS
LEFT JOIN TABLE_GROUPS
ON TABLE_USERS.group = TABLE_GROUPS.id
You want a JOIN:
SELECT
u.id,
username,
groupname
FROM
TABLE_USERS AS u
LEFT JOIN TABLE_GROUPS AS g
ON u.group = g.id