So Lets say I have a user table and then a user_profile table. To connect the relationship there would be a user_id row within the user_profile table. Now when I'm building my applications I like to make my url show the username and not the user_id example:
http://www.example.com/username/profile
not:
http://www.example.com/user_id/profile
So what I find myself doing is getting the user_id through the username and then fetching the profile info which just adds an extra query for no reason. My questions is could I just make the relationship through the username which is just as unique as the id row in the users table. Or is this bad practice and I should stick with using user_id?
A much better idea would be to use the user_id to join the tables, but provide the username as a parameter. Something like:
select p.*
from users u
, profiles p
where u.id = p.user_id
and u.username = ?
Related
I have a roles table which contains various user roles.
A pivot tables joins this to my users table.
users
id | name
roles
id | title
user_role
user_id | role_id
I would like to display all roles that exist and pre tick the ones that belong to a specific user.
How would I go about this, I take it I cannot do this in mySQL?
I was considering getting all roles with one query, then with another query get all roles that belong to a specific user.
Then loop through all roles and if there is a match with the specific users roles, output a checked box instead of an unchecked one.
Is there a better way?
Something like
SELECT R.id as role_id,
R.title as role_title,
UR.user_id as user_id,
U.name as user_name
FROM Roles R
LEFT JOIN user_role UR
ON UR.role_id = R.id
AND UR.user_id = :myuserid
LEFT JOIN users U
ON U.id = UR.user_id
should return a complete list of roles, with either a NULL or the user id in the user column to indicate any roles that the user has been granted (user identified by id as :myuserid)
I think normal SQL Query can do most of the work: Checkout this SQLFIddle for sample of what your query might look like
SELECT r.* FROM roles r LEFT JOIN user_role ur ON r.id=ur.role_id WHERE ur.user_id=3;
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.
From what I've been reading online, I understood that it's better to split the data into more tables, if possible because of the access times.
Right now I have a table in which I am storing usernames, passwords and join date
This is how my table looks:
'user'
'user_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
user_username VARCHAR(80) NOT NULL,
user_password VARCHAR(255) NOT NULL,
user_join_date INTEGER UNSIGNED NOT NULL,
PRIMARY KEY (user_id) ');
I am trying to create a new table called profiles in which I want to store first name, last name, email, age and gender. What I think is that I need a one-to-one relationship, so I should be using the user_id but I'm not really sure how to implement it.
Should I create another table called profiles with
profiles
profiles_id
first_name
last_name
email
age
gender
and another one which should be the relationship ? e.g.
user_profiles
----------
user_id
profiles_id
Is this right? How would the SQL look for the user_profiles?
Thanks
Don't split the tables. Just add the new columns to your existing user table. You might find later on that splitting tables is a good idea based on actual queries and usage patterns but until you have that kind of data, keep things simple.
If you must create a profile table, don't create a user_profiles table. That would allow an m-to-n relationship which is probably not what you want. A simple user_id column in profiles is better. In fact, it could be both a foreign key and the primary key to make sure that each user row only have one and only one profile row (although by splitting the tables you might still have a user with no profile).
Usually, you create an association table, like user_profiles you have described when one user could have more than one profile, and/or one profile could belong to one or more user.
As you have said, here you have a one-to-one relationship between user and profile. So, you can simply add a user_id column to your profile table, and define it as a foreign key to user table.
Then, a simple JOIN will allow you to query both tables at the same time:
SELECT u.*, p.*
FROM user u
JOIN profile p ON u.user_id = p.user_id
Add a new field in the User table, ProfileId, and set it as Foreign Key (FK). Each time you create a User, you have to assign to it a profile (which will be the ProfileId PK from profile table).
If you want to see also the profile information of a user, you have to do a join
Select username, first_name,second_name
From user u, profile p
Where u.profileId = p.profileId
this
user_profiles
----------
user_id
profiles_id
is used in a many-to-many relationship. By example, you want to assign to an admin some privileges, but those privileges can be also assigned to more admins. Then, you have to create a 3rd table to solve this problem. Here is an example, but you don't need to do this.
You could add a user_id field to your profiles table and JOIN the tables on user_id.
SELECT user.user_username, ..., profiles.first_name, ...
FROM user
INNER JOIN profiles
ON user.user_id = profiles.user_id
This should fetch data combining information from those rows where the JOIN condition is met (i.e. user.user_id = profiles.user_id).
It is true that having more than one tables is a good idea. I am not sure what you mean about access time, but there are other advantages.
- Your users database containing passwords etc is "sacred", you never change its structure and you limit the rights to it (read, write) to the strict minimum.
- You can then have several "satelites" tables such as profiles, private messages, etc which are more flexible, less sensitive and which you can change all the time.
About your question per se, there is no need for a separate table with the relationships. In fact is a very bad idea which will complicate your queries and doesn't have any advantage. Instead, in your profiles database you will have one column that refers back to the user id.
users
--------
id
user_name
email
password
users_profiles
---------
id
user_id
favourite_animal
Table user
user_id |user_username |user_password |user_join_date |profile_id
Table profile
profile_id |first name |last name |email |age |gender
When selecting a user by user id:
SELECT u.*, p.* FROM user AS u INNER JOIN `profile` AS p ON u.profile_id = p.profile_id WHERE u.user_id = 1
But a user should only one gender, one age, one name and surname. Maybe e-mail adresses might be many. I suggest you there is no need to join tables which have a 1-to-1 relation. Instead merge those tables.
I have a form set up where the user can enter in the username or lastname of a person. I then take either the username or lastname depending on what they entered and query the database and displaying all the userinformation and whether they have access to certain areas. There are two tables I need to query and get all the information for the user entered. I'm assuming you use a JOIN but I'm not quite sure how to do it. Right now I have the query to grab all the data from the users table I just need help adding in the second table. The two tables look like this
Users {
uid
username
password
firstname
lastname
email
}
userAccess {
uid
assessment
development
learningmodule
project
}
The SQL I have so far is
SELECT *
FROM Users
WHERE username = '$username' OR lastname = '$lastname'
You are right you'll need to use a join. This type of join is called an Inner Join. You can achieve it like this:
SELECT * from Users, userAccess WHERE Users.uid = userAccess.uid AND Users.uid = #;
I'm guessing you'll have an id column that is the Primary Key for your userAccess table as well. The above query will provide the data from both tables in 1 record for every condition where the above statement is true.
If you are using MySQL you can read more about joins here:
http://dev.mysql.com/doc/refman/5.0/en/join.html
You donĀ“t mention which database you are using, although I'm guessing MySql.
What you need to do is a simple inner join:
SELECT u.uid
u.username,
u.password,
u.firstname,
u.lastname,
u.email,
ua.assessment,
ua.development,
ua.learningmodule,
ua.project
FROM Users u
INNER JOIN UserAccess ua
ON u.uid = ua.uid
WHERE u.firstname LIKE '%$username%' OR u.lastname LIKE '%$lastname%';
Do note that I'm not selecting the uid again in the UserAccess table as it is redundant since you already selected it from the Users table and since you are joining by that key you don't need it again.
Also note that instead of using the equal operator (=) I use the LIKE operator since there are more chances that you want to filter information based on partial info such as keywords and not full words.
I'd recommend you to have a look at a SQL tutorial for beginners. This one seems to be good enough.
I'd also recommend you to read the guidelines on how to post questions here or else you won't get much attention from anybody, plus they will downvote you :)
user_info table:
ui_id - PK
name
created_by - FK
users table:
user_id- PK
username
I want to display the content of user_info table. The created_by field are user_ids from users table, I want to change it into username when displaying it.
Is it possible in a single query? Please tell me how.
This would do
select ui.*, u.username from user_info ui
join users u on u.id = ui.created_by
Simply join the tables.