I'm new to advanced MySQL having only come across many-to-many relationships yesterday. I'm working on a project where users can join multiple projects and projects can accommodate multiple users.
My tables are:
Users - ID, name, email, password etc
Projects - ID, name, URL etc
Following advice from this site, I have set up a linking table with two foreign keys matched to the IDs of the above tables:
Users_Projects - Users_ID, Projects_ID
I understand the next step is something to do with joining, but how do I add a user to a table, or see who the members of a project are/what projects a particular user is a member of?
Projects for a given user:
SELECT *
FROM Projects p
LEFT JOIN users_projects up ON p.projects_id = up.projects_id
WHERE up.users_id = [INSERT USERID HERE]
To assign user to project you need to type user id and project id into the User_Projects table, to see which users are in selected project you can type:
SELECT Users.name, Users.email etc.. from Users_Projects JOIN Users on Users.ID =
Users_Projects.Users_ID JOIN Projects ON Projects.ID = Users_Projects.Projects_ID WHERE (Put your where statement here)
Read more on wiki: JOIN wikipedia
I think you forgot an id (in users, create new fields 'projectid' on user table)
ADD USER => INSERT INTO users (name,email,...) VALUES ('fred','redeyes#XX.com',...);
CHECK USER => SELECT name, email FROM USERS;
CHECK USER BY PROJECT ID => SELECT name, email FROM USERS, PROJECTS WHERE USERS.projectid = PROJECTS.id
Related
I'm doing I'm having a bit of a problem performing a query in my university project. I got a website where users share the books that they've read and I have a page where the user can view the books he has added (the books he owns).
For that I believe I need the logged user's id, which I store in a session PHP variable, the user id is in table users.
The information about the books is stored in a table books and it has its own id primary key.
Then, to show who owns what I have a table owns_book (id, u_id, book_id).
Right now for testing I've got 26 books total, 25 of them are added by a user with id of 57 and 1 book by user with id of 49.
When I run this query:
SELECT id, title, author, category, cover, added, user_id FROM books, users
WHERE user_id=49 AND id IN(SELECT book_id FROM owns_book)
AND user_id IN(SELECT u_id FROM owns_book)
And the result is a mess, I don't get the expected one book, I also get books added by the other user.
Can someone please show me the correct query that I need or if I need to change the structure of my tables? Thanks.
EDIT:
users(user_id, ...)
books(id, title, author, publisher, published, cover... )
owns_book(id, u_id, book_id)
It looks like you're looking to to grab everything from your books table that is owned by a specific customer. If that's the case, you can try
SELECT * FROM books
JOIN owns_book
ON books.id = owns_books.book_id
WHERE owns_book.user_id = 49
This will select all of the props from your books table then joins the tables based on on the ID of the book being equal to the book_id of the owns_book. Lastly, add the parameter - you only want to see user_id = 49.
You can simplify this query and use a LEFT JOIN...
SELECT books.id, title, author, category, cover, added, users.user_id
FROM users
LEFT JOIN owns_book on owns_book.user_id = users.user_id
LEFT JOIN books on books.id = owns_book.id
WHERE users.user_id=49
This links the user_id and lists any books owned by this user_id ( the ON bit of the JOIN). The WHERE clause just limits to listing records for the user_id your after.
If in the main list of columns, there is a column on multiple tables ( like user_id) then prefix it with the table name to allow the database to detect which column you want to use (even though they may be the same value).
You could also use inner join to join the tables users and books with the owns_book table:
SELECT id, title, author, category, cover, added, user_id
FROM owns_book
INNER JOIN users ON users.id = owns_book.u_id
INNER JOIN books ON books.id = owns_book.book_id
WHERE users.user_id=49
I am creating a site that allows users to view desired 'teams' and can then join them with the click of one button.
I have my users table which contains: user_id, user_name, team_id
Then, I have my teams table which contains: team_id, team_name, team_players
How would I go about having the users to join a group, each user can also only be in 1 team at a time.
If you want each user to be able to join multiple teams, and each team to have multiple users, then you need a "join table."
Table teams_users would contain team_id, user_id. You can make a composite primary key on team_id, user_id (preventing a user from joining the same team twice).
Then you can get a team with:
SELECT * FROM users t1 right join teams_users t2 ON t1.team_id = t2.team_id WHERE t2.team_name = 'the rascals'
Even if you only want players to join one team at a time, you might still want to use the join table in case you ever change your mind. It would be very easy. To only allow one team per user, put a unique constraint on user_id in the join table. If you later decide you want to allow multiple teams, you just remove that constraint.
If a user tries the "join team" action, you simply check for the user_id's existence in the join table.
SELECT * FROM teams_users WHERE user_id = $user_id
If it does exist, you retrieve its matching team_id and tell them, "sorry, you are already in team 'the rascals'. You must leave that team if you want to join another." If they drop their team, you simply do:
DELETE from teams_users WHERE user_id = 5
If they add a team, you just do:
INSERT INTO teams_users ($team_id, $user_id) #// (assuming PHP variables).
The INSERT query will only work if they are not already in a team. If they are you would get an error message. You could also look at "INSERT ON DUPLICATE KEY UPDATE ..." queries. But I would advise against that because you want to warn users before they change teams.
You should start by adding the team_id field to the users table as a foreign key and allow it to be NULL.
Then you would display the team names in an html form with a radio button for each team.
In a PHP file (which should be set to the action of your form) create an if statement based on the values you assigned to each radio button. In each if block, execute a sql UPDATE statement that will add the appropriate group_ID to the right user instance.
I have a logical problem with my database, let me explain. There is my system:
I have users and admins.
Admins can create project and if they needed they can add the related users on the project.
1 user can work many projects and 1 project can have many users.(many to many)
I build relational database and it works fine. But the problem is, which users are working on which project(s) ? I don't know how to INSERT them to database. Admins can choose the users from the list and then the selected users should stored with the dependent project. But I couldn't managed to INSERT it to database. Here my tables and some codes.
--projects-- --users-- --projectUsers--
userId userId userId
creationDate registerDate projectId
projectId email
title permission
priority name
content surname
endDate birthDate
password
$sql="INSERT INTO projects (
projectId,
userId,
creationDate,
title,
priority,
content,
endDate
)VALUES(
'$projectId',
'$userId',
'$creationDate',
'$title',
'$priority',
'$content',
'$endDate'
)";
$result=mysql_query($sql) or die (mysql_error());
$sql2="INSERT INTO projectUsers (
projectId,
userId
)VALUES(
'$projectId',
'$userId'
)";
$result2=mysql_query($sql2) or die (mysql_error());
The table "projectUsers" stores 2 foreign keys. When the admin creates a project, his userId and the new projectId stores on the "projectUsers" and also stores on the "projects" table. But admin will choose the which users will depended with this project, and he can choose more then one in once. How should I INSERT the dependent users on the data base. And also I don't want to store more then 1 user in a row. And I should able to get answer this queries:
which users are working on which project(s) ?
which users are working on this project ?
This user working on which(s) project ?
Example: Admin creates a new project and select 3 dependent users. I want to insert them the table "projectUsers".When admin creates the project, I want to see my "projectUser" table like this:
userId projectId
1 1
2 1
3 1
P.S: The "userId" on the "projects" table shows me the who created this project. Like an owner.
Remove the userId from your projects table, you're storing that information in the ProjectUsers association table anyway. For every user working on a project, you have to create a separate row in the ProjectUsers table.
From there on, all your retrieval queries are just basic three table joins:
1. Which users are working on which project(s)?
SELECT * FROM Projects p
LEFT JOIN ProjectUsers pu
ON p.projectId = pu.projectId
LEFT JOIN Users u
ON pu.userId = u.userId
2. Which users are working on this project?
SELECT * FROM Projects p
LEFT JOIN ProjectUsers pu
ON p.projectId = 123 AND p.projectId = pu.projectId
LEFT JOIN Users u
ON pu.userId = u.userId
3. This user is working on which projects?
SELECT * FROM Users u
LEFT JOIN ProjectUsers pu
ON u.userId = 123 AND u.userId = pu.userId
LEFT JOIN Projects p
ON pu.projectId = p.projectId
The Projects and Users need to be created first for the foreign key, then simply 1, 2 & 3. Add each user for each project that is selected.
INSERT INTO ProjectUsers (userId, projectId) VALUES (1, 1);
INSERT INTO ProjectUsers (userId, projectId) VALUES (2, 1);
INSERT INTO ProjectUsers (userId, projectId) VALUES (3, 1);
Other than this we are really struggling to understand the context of your problem. You've tagged the problem as SQL, but you have the query to do the INSERT correct. What we don't have is a full definition of the table - if that is raising errors.
If you're problem is is within the PHP, then you've got too many SQL tags, because that is what people are trying to solve.
Please, Please, Please change the UserId in Projects to be OwnerUserId - the description about what this data field represents is as important as indicating what table it joins to, so concatenating these together gives full meaning to the field, and removes ambiguity.
I have 5 tables:
user ( user id, user name, etc.. )
role ( role_id, role_name )
user_role ( user_id, roles_id )
form ( form_id, form_name, etc.. )
form_access ( form_id, role_id )
user contains all registered user data.
role contains all different types of roles.
user_role contains which user has which role (all assigned roles are stored)
form contains all form data.
form_access contains data like which user role has which form access(one form can be assigned to many user roles).
I wanted to write a SQL query in PHP to retrieve form name based on the user logged in and his role, e.g. if Admin logs in he should get all forms, if HR logs in he should get forms related to HR only.
I tried this query:
$query = "SELECT ur.role_id, f.form_name, f.form_desc
FROM user_role ur, froms f
WHERE users.id = '".$user."',
users.status ='A',
forms.form_id = form_access.form_id,
from_access.role_id = user_role.role_id,
user_role.role_id = '".$user."'";`
Some one help me out with the correct query?
Since you start from the user_id you'll want to select from user_role and JOIN form_access and form.
SELECT `form`.`form_name` AS `form_name`
FROM `user_role` AS `ur`
INNER JOIN `form_access` AS `fa` ON `fa`.`role_id` = `ur`.`role_id`
INNER JOIN `form` AS `f` ON `f`.`form_id` = `fa`.`form_id`
WHERE `ur`.`user_id` = '".$user."'
PS: Check the table and column names.
You have to use AND .
BUT this should be better with joins.
$query = "SELECT ur.role_id, f.form_name, f.form_desc
FROM from_access
INNER JOIN froms f ON forms.form_id = form_access.form_id
INNER JOIN user_role ur ON from_access.role_id = user_role.role_id
INNER JOIN users ON users.id = user_role.role_id
WHERE users.id = '".$user."'
AND users.status ='A' ";
Your query is entirely broken, the others may have provided you with solutions but I'm going to give you some advice.
You've written an entire query, tried it, and it failed. I write queries all day long but if I write a whole query in Notepad then execute it it's probably going to have some minor error in it somewhere too.
Start from the ground up. You're trying to get a list of forms the user has access to, so lets start with the forms_access table. So what's the most basic starting point? How about:
SELECT fa.role_id, fa.form_id
FROM forms_access fa
Ok, thats overly simplified but if that ran at least we know we're connected to the database.
So we can easily tell which form_ids each role has access to. Now we know our linking table to users is user_roles, so let's add that in:
SELECT ur.user_id, fa.form_id, fa.role_id
FROM forms_access fa
INNER JOIN user_roles ur ON fa.role_id = ur.role_id
So we've joined forms_access to user_roles on the foreign key role_id. Now we can see for every user_id, which role_id they have and which form_ids they can access.
So we're pretty much there, we just need the information from the forms table, so lets JOIN to that too:
SELECT ur.user_id, f.form_name, f.form_desc, fa.form_id, fa.role_id
FROM forms_access fa
INNER JOIN user_roles ur ON ur.role_id = fa.role_id
INNER JOIN forms f ON f.form_id = ur.form_id
Great! Now we have a list of each form_name/form_desc that each user_id can access.
Try the above step by step, if you skip to the end there could well be an error since I have not tested the code, and I don't know for sure that your table definitions match the question. If you do it step by step you only need to check the most recently added line to find the error.
I have just noticed in the question that you also need users.status = 'A', so in the same way as above you'll need to join to the users table on an appropriate foreign key, give it a go.
Now, once you've done all that you need to filter the results to a specific user_id - notice up till this point we haven't bothered with the WHERE clause.
Now don't go adding some variant of WHERE user_id = '$user' right away because then you've introduced 2 potential errors. Instead try adding WHERE user_id = 0 (or some known user_id). Does the query run and the results look correct? Great, now finally try adding in your php variable.
I've currently got two tables:
mems (members):
id,
name,
email,
password,
salt,
achievements_id
achievements:
id,
achievement,
description,
points
I am able to correctly display the data for a user with:
"SELECT * FROM achievements WHERE id IN (SELECT achievements_id FROM mems WHERE name = '$name')";
My question is, how do I add the achievement ID to the user so each user has their own achievement records? Currently if I use an update it just wipes over the old achievement so it only ever displays 1 record.
Say I have 2 achievements and 2 users
User 1 achieves achievement 1, it's viewable and they have achievements_id set to 1.
User 2 achieves achievement 1, it's viewable and they have achievements_id set to 1.
User 1 then achieves achievement 2, it's viewable but now they have achievements_id set to 2.
I have no clue how to do this. I know what I want to do, but no clue how to design the database to have each user having their own records of achievements.
I originally did it where achievements table had a member_id and I'd concat the other users ID into their, dodgy but it semi-worked.
Any help? Sorry if I am making no sense.
It sounds like what you need is to model a many-to-many relationship (many users can share the same achievement - ie. be linked to the same entitiy in the achievements table; while a single user can have multiple achievements). This is usually done using an extra table. Let's call it: Members_Achievements_Map.
CREATE TABLE Members_Achievements_Map (
MemberID,
AchievementID
)
This table would link entities from the members table to entities in the achievements table.
The way I would go about this would be to create another table to hold the users achievements.
So basically another table that looks like such:
UserAchievements:
userID, achievementID
That way you can join the tables like:
SELECT * FROM achievements a
INNER JOIN userAchievements uA ON uA.achievementID = a.id
INNER JOIN users u ON uA.userID = u.id
That will give you all the users for all the different achievements.
Hope that helps!