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.
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'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!
I'm having some trouble figuring out how I should build my database for this project i'm currently working on. Fishing-related.
I'm just not sure how to set up my tables.
Table 1(ID, username, email etc)
Table 2(fish, weight, length etc)
How do i join these two tables? Should I have a column named ID in the 2nd table aswell? Because I need to know which user uploaded what fish. I'm just not sure how to do that.
Any help is appreciated.
Yes you have to, and that is called Relation Databases this is example
Users (UserID, UserName, Password)
Fish (FishID, UserID, FishName, Length, Weight)
and then you connect them using UserID
select u.UserName, f.FishName, f.Length, f.Weight
from Users u
LEFT JOIN Fish f on (f.UserID=u.UserID)
and if you are looking for specific user then just add at the end
WHERE u.UserID=#UserID
Looking at you're table structure I think it's best to change the id name in table 1 to *user_id* and add a column in the second table also named *user_id*. Joining using the columns is then very simple using the following query:
SELECT *
FROM table1
JOIN table2 USING (user_id)
Other possibility would be to add a column named *user_id* (or something else) to table2 and create a query like:
SELECT *
FROM table1
JOIN table2 ON table2.user_id = table1.id
In this case, you set the columns to use for the join in the 'ON .. = ..' structure.
The site I'm working on has 3 different types of users: admin, applicants, reviewers. Each of these groups will have some basic info that will need to be stored (name, id, email, etc) as well as some data that is unique to each. I have created a users table as well as a table for each of the specific groups to store their unique data.
users: id, f_name, l_name, email, user_type
users_admin: id, user_id, office, emp_id
users_applicant: id, user_id, dob, address
users_reviewer: id, user_id, active_status, address, phone
If a user with user_type of "1" (applicant) logs in I will need to JOIN to the users_applicants table to retrieve their full record. I tried using a UNION but my tables have vastly different columns.
Is there a way to, based on a user's type, write a conditional query that will JOIN to the correct table? Am I going about this completely the wrong way?
Thank's in advance for your help!
Well, in the end your tables are already flawed. Why even have a table for each type? Why not put all those fields into the users table, or maybe a user_details table (if you really want an extra table for non-general data fields)? Currently, you're actually creating 4 independent user tables from a relational point of view.
So why do the type-tables have a surrogate key? Why isn't the user_id already the (only) primary key?
If you changed that, all you would need is the user id to retrieve the data you want, and you've already got that (or you wouldn't even be able to retrieve the user type).
Either you do it programmatically, or you can do this with a series of CASEs and LEFT JOINs.
For simplicity's sake let's do this with a table users where you can have a user of type 1 (normal user), 2 (power user) or 3 (administrator). Normal users have an email but no telephone, power users have an address and a field dubbed "superpower", and administrators have a telephone number and nothing else.
Since you want to use the same SELECT for all, of course you need to place all these in your SELECT:
SELECT user.id, user.type, email, address, superpower, telephone
and you will then need to LEFT JOIN to recover these
FROM user
LEFT JOIN users_data ON (user.id = users_data.user_id)
LEFT JOIN power_data ON (user.id = power_data.user_id)
LEFT JOIN admin_info ON (user.id = admin_info.user_id)
Now the "unused" fields will be NULL, but you can supply defaults:
SELECT
CASE WHEN user.type = 0 THEN email ELSE 'nobody#nowhere.com' END AS email,
CASE WHEN user.type = 1 OR user.type = 2 THEN ... ELSE ... END as whatever,
...
Specific WHERE conditions you can put in the JOIN itself, e.g. if you only want administrators from the J sector, you can use
LEFT JOIN admin_info ON (user.id = admin_info.user_id AND admin_info.sector = 'J')
The total query time should not be too bad, seeing as most of the JOINs will return little (and, if you specify a user ID, they will actually return nothing very quickly).
You could also do the same using a UNION, which would be even faster:
SELECT user.id, 'default' AS email, 'othermissingfield' AS missingfieldinthistable,
... FROM user JOIN user_data ON (user.id = user_data.user_id)
WHERE ...
UNION
SELECT user.id, email, 'othermissingfield' AS missingfieldinthistable,
... FROM user JOIN power_data ON (user.id = power_data.user_id)
WHERE ...
UNION
...
Now, if you specify the user ID, all queries except one will fail very fast. Each query has the same WHERE repeated plus any table-specific conditions. The UNION version is less maintainable (unless you generate it programmatically), but ought to be marginally faster.
In all cases, you'll be well advised in keeping updated indexes on the appropriate fields.
Instead i will suggest you reconstruct you tables structure like this.
Create a table
users_types :
id
type
Then create another table users with a foreign key
users :
id
f_name
l_name
email
office
emp_id
dob
address
active_status
phone
users_types_id
And now when you need to insert data insert null in the fields which are not required for a particular user. And you can simply fetch records on the basis of id. Also using left join will give you the name of user type.
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