I have two tables in my sql:
Users :
id name roleid
1 David 1
2 Sean 2
3 Joe 1
Roles:
roleid desc
1 copy
2 delete
3 move
Now i use this cmd to select the user with the user permission
SELECT * FROM Users u INNER JOIN Roles r ON u.roleid = r.roleid
Now i want to know if it's possible to build SQL Table(Roles Table), that it's will be dynamically the number of roleid for each user. something like:
Users :
id name roleid roleid2 roleid3
1 David 1 2 3
2 Sean 2
3 Joe 1 3
Use an associative entity to address the many-to-many relationship between Users and Roles. A composite primary key in the UserRole table will prevent duplicate assignment of roles, and foreign keys referencing the Users and Roles table will preserve referential integrity.
See SQL fiddle for a sample implementation.
At first, I suggest you to use many to many relationship. It means trird table: UsersRoles (userid,roleid)
At second, it's impossible create dynamic number of columns in typical SQL statement. But its possible by using stored procedures.
here is working example
sqlfiddle
Related
I have User table which contains same user represented by different entities all around. For example
User Table
==========================
id name
1 John Doe
2 Doe, John
3 Nicholas Cage
4 BlackRiderXXX
5 Nicholas cage
where users John Doe, Doe, John, BlackRiderXXX are the same people. Also, Nicholas Cage and Nicholas cage are the same people. Other tables refer to user.id randomly based on which user object did the action.
For Action table it'll look like
Action Table
==========================
id user_id some_other_stuff
1 1 ...
2 2 ...
3 1 ...
4 4 ...
5 3 ...
Where the actions 1,2,3,4 are all done by John Doe.
I'll have these users merged by the user manually meaning we'd know who is whom. They'd also select which User is the one they'd like to be as their main user account so we need to know this information as well.
I'm simplifiying a bit but I have a dozen tables which are like the Action table I provided above. We have mainly two use cases on how we will need to query:
1) Find actions which are done by user X (which should check all the users entities belonging to user X)
2) Find actions and group unique users
Main point is we will be using it everywhere around the codebase on 100+ queries so we want to design it well. How can I construct a system where the query will be simple enough also powerful enough to handle different querying ways?
Thanks
PS: We are using PostgreSQL
Why not include the "main" user in the first table?
User Table
id name main_user_id
1 John Doe 1
2 Doe, John 1
3 Nicholas Cage 2
4 BlackRiderXXX 1
5 Nicholas cage 2
Then you would join on:
select . . .
from actions a join
users u
on a.user_id = u.id
where u.main_user_id = 1;
If you want this selectable per end user, then use a different table:
create table end_user_users (
end_user_users_id serial primary key,
end_user_id int references end_users (end_user_id),
end_user_user_id int references users (id),
end_user_main_user_id int references users (id)
);
Then the query would look like:
select . . .
from actions a join
end_users_users euu
on euu.end_user_user_id = a.user_id and
euu.end_user_id = $my_id
where euu.end_user_main_user_id = 1;
You can use regexp_replace(),initcap() and trim() functions to refine and extract the common name strings to be grouped, and then generate values for newly created action_id column depending on them :
with new_action0 as
(
select u.id as id,
case when strpos(u.name,',') > 0 then
initcap(trim(regexp_replace(trim(u.name),'(.*),(.*)','\2 \1')))
else
case when lower(trim(u.name))='blackriderxxx' then
'John Doe'
else
trim(initcap(u.name))
end
end as name
from action u
)
select n.id, dense_rank() over (order by n.name) as user_id
from new_action0 n;
Demo
A new decent user table can be created by using this query with create table .. as statement
Is there a way to compare bitmasks in the h2 database, similar to what has been asked in Comparing two bitmasks in SQL to see if any of the bits match ?
Having a table of users with different roles, I'd like to select all users that are programmers.
User Table
----------
ID Username Roles
1 Dave 6
2 Charlie 2
3 Susan 4
4 Nick 1
Roles Table
-----------
ID Role
1 Admin
2 Programmer
4 Designer
The select should be something like
SELECT * FROM UserTable WHERE Roles & 2 != 0
I know there is a BIT_AND function in h2 but do not know how to use it.
I was confused by the BITAND and BIT_AND functions. The select statement should look like
SELECT * FROM UserTable WHERE BITAND(Roles, 2) != 0
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 looking for a design pattern to manage records in a relational database which belong together, e.g. grouping multiple contacts. The group itself does not need to be an entity. A group should have an unlimited count of members.
It should be possible to run a query to get other group members of a given record.
My idea is to manage it in one table:
GROUPINGS
integer group
integer member_id
primary_key (group, member_id)
foreign_key (member_id)
EDIT: Beware that group is not a foreign key. It's just a unique identifier. It should be increased for every member group which is built.
Here is an example content:
GROUPINGS group | member_id
-----------------
1 | 10
1 | 11
1 | 12
2 | 20
2 | 21
3 | 10
3 | 40
This example contains three groups: (10,11,12) and (20,21) and (10,40). You see that 10 is included in two groups.
To query the "neighbors" of member 10 we can use this SQL statement:
SELECT g2.member_id
FROM groupings g1
JOIN groupings g2 ON g1.group = g2.group
AND g1.member_id != g2.member_id
WHERE g1.member_id = 10
=> 11,12,40
What do you think? Perhaps this is a known pattern - are there links to find more about this?
EDIT: Renamed table "groups" to "groupings" and renamed attribute "group_id" to "group" to make it obvious that a record in this table is not a group - it's a link between a group and a member. Group is not an entity.
What you have outlined is a pretty standard solution, a relational table between two entities - Group and Member. I am sure there are alternatives, but this is the solution I would go with.
Looks fine to me - is a normal solution to end at if a member can be part of multiple groups, which presumably they can.
The only suggestion I'd make is with your SQL query - I'd use a JOIN instead, but that's nothing to do with your schema:
SELECT g2.member_id
FROM groups g1
INNER JOIN groups g2 ON g1.group_id = g2.group_id AND g1.member_id <> g2.member_id
WHERE g1.member_id = 10
I have a table called auctions, which has various columns such as username, auction id(the primary key), firstname, lastname, location etc, as well as a category column. The category column is blank by default, unless it is filled in for a particular record by a user.
I have made a new users table, which has username and category columns, as well as aditional fields which will be completed by user input.
I would like to know if it is possible when updating a record in the auctions table to have a category, to insert the username and category from that record into the users table as long as the username is not already present in the table.
For example, if I have the following tables:
auctions
auctionid username firstname lastname category
------------------------------------------------------------------------
1 zerocool john henry
2 fredflint fred smith
3 azazal mike cutter
Then, upon updating the second record to have a catagory like so:
2 fredflintsoner fred smith shoes
The resulting users table should be:
users
username shoes pants belts misc1 misc2
--------------------------------------------------
fredflint true
With no record have existed previously.
If additional auctions exist with the same username in the auctions table, such as:
7 fredflint fred smith belts
Then even if this auction is added to the category, a new record should not be inserted for the users table, as the username is already , however it should be updated as necessary, resulting in:
username shoes pants belts misc1 misc2
--------------------------------------------------
fredflint true true
What you are looking for is known as a TRIGGER. You can specify something to run after every insert/update in the auctions table and then determine what to do to the users table.
A couple of questions come to mind. The first is, your user table looks denormalized. What happens when you add a new category? Consider a user table in the form of:
id username category
Where you have multiple rows if a user has multiple categories:
1 fredflint shoes
2 fredflint pants
....
The second question I have is, why do you need a user table at all? It looks like all the information in the user table is already stored in the auction table! You can retrieve the user table simply by:
select distinct username, category
from auctions
If you need the separate table, an option to manually update the table when you create a new auction. I'd do it like this (I know just enough about triggers to avoid them):
1 - Make sure there's a row for this user
if not exists (select * from users where username = 'fredflint')
insert into users (username) values ('fredflint')
2 - Make sure he the shoe category
if not exists (select * from users where username = 'fredflint' and shoes = 1)
update users set shoes = 1 where username = 'fredflint'