I have been doing this for a while now, via some php, first lets say we have two tables:
Users
user_id name email
Images
image_id user_id url
user_id and user_id from images table would be linked with a relationship.
Now what I would do is select the user by their Id, check if the user is found, if so then make another query to images table, and check for num rows and loop through the return, is there a function that I could use that would allow me to just select the user and all the images that are linked to the user without doing a joint query.
Thank you for any help
When you say "without doing a joint query" I think you mean "without doing two queries."
In fact, what you want is probably a LEFT JOIN. The idea is that you select users from the user table matching some ID, and LEFT JOIN the images table. The left join will give you null values if no images exist for the user. If you use a normal join, the fact that no matching records exist in the images table will result in no rows returned.
Here is an example:
SELECT u.name, u.email, i.url
FROM Users u
LEFT JOIN Images i ON (i.user_id = u.user_id)
WHERE u.id = #SpecificUserID;
Assuming the user id is found and there are some images for that user, you will get a result that looks like this:
name email url
----- ----- -----
John j#a.com abc.jpg
John j#a.com def.jpg
John j#a.com ghi.jpg
Now as you can see, the name and email values keep repeating. You get a unique image url for each row and the matching username and email.
If you only select one user at a time, this is simple to process in a loop. On the first iteration read all three values. On subsequent iterations just read the url, adding it to your list or array.
Here is a useful tutorial on joins: Understanding JOINs in MySQL and Other Relational Databases
This can be done in one query rather than two by using an inner join to get your result set.
$sql = "SELECT u.user_nid, i.url
FROM tbl_user u
INNER JOIN i.user_nid = u.user_nid
WHERE user_nid = ?"
With this query you will receive a list of the users images and if there are no images returned or the user does not exist, than you will have a row return of zero.
You'll have to use a join to retrieve data from multiple tables in a single query.
The foreign key relationships enforce constraints. Ex: You can't insert a record into Table A referring to a key in Table B without the record actually being in Table B.
Related
I have two tables one is user and another is images. I gave users the option to select multiple images. I can store multiple images with same user_id in database, but when I am trying to get one image from every user I am getting all the images.
My query is something like this:
$query = "
SELECT *
FROM images i
JOIN users u
ON u.user_id = i.user_id
LIMIT 1";
When I run this query in while() loop, I only get very first image from images table.
I am really sorry if I am not able to clarify what I am try to ask.
Have you tried something like this:
SELECT * FROM users u INNER JOIN images i ON u.user_id = i.user_id GROUP BY u.user_id;
This should return you only one record from user/image tables for each user that has an image.
Don't run queries in a while loop. Instead, use one query to get all the desired records.
If you insist on running your query in a loop, then you are missing WHERE users.user_id = ? part in your query, so you can get a different result for each user in a loop.
you can do this without using join. simple select user and fetch data and on the bases of 'id' add query to get image. i hope this will help you;
Your current query:-
SELECT *
FROM images i
JOIN users u
ON u.user_id = i.user_id
LIMIT 1
uses LIMIT 1. This tells the query to bring back 1 row.
Removing the LIMIT 1 will return 1 or more records per user (who has at least 1 image), one for each image.
If you want a single user then it is possible (although not recommended) to (ab)use the GROUP BY clause:-
SELECT *
FROM images i
JOIN users u
ON u.user_id = i.user_id
GROUP BY u.user_id
This would bring back one record per user, but which image it returns is not defined. It could bring back the first image for that user, or the last one, or any other one (and which one it returns could change in the future). Further, there is no actual reason it couldn't return values from different rows for each of the columns on the images table (unlikely, but nothing specified to stop this happening).
Note that basic SQL standards specify (with a small exception) that any non aggregate field brought back in a SELECT statement must be in the GROUP BY clause. MySQL used to not enforce this restriction by default, but recently this changed and it is enforced by default. As such by default this query would no longer work as it is returning all the fields from the images and users tables while only specifying the user_id from the users table in the GROUP BY clause.
What you should do is define which image you want for each user. Assuming the first image (and that the images table uses an auto increment primary key called id):-
SELECT u.*,
i.*
FROM users u
LEFT OUTER JOIN
(
SELECT user_id
MIN(id) AS first_image_id
FROM images
GROUP BY user_id
) sub0
ON u.user_id = sub0.user_id
LEFT OUTER JOIN images i
ON sub0.user_id = i.user_id AND sub0.first_image_id = i.id
This uses a sub query to get the first image id for each user. Then that is joined to the images table to get the other details for that image from the images table.
Note I have used LEFT OUTER JOIN. This is to return a row for a user who doesn't have any images uploaded.
Note it is generally a bad idea to use SELECT *, rather than specifying the columns to be returned. I have left this in place here as I do not know the column names of your tables.
I have a database table for a user of my website, this table gives each user a user_id.
Using normalization, I have linked the user to a group with a user_group table including user_id and group_id to link a user to a group.
I then have a group table that links a group name to the group_id.
I am trying to output the users on my webpage in a list next to the name of the group, not its id.
I was thinking of using a foreach loop to do this, but the data would need to get into one array? I dont know how I would take the user_id, find out which group _id it it paired with, find out which group name that id was paired with, and then add that to the array with the names and be able to display the group name next to the user's name using foreach.
Thanks for any help.
If i understand you correctly, you want to join you users data to group to show the user details with their group name.
Try out this:
select u.*,g.*,ug.* from users u
left join user_group ug on u.user_id=ug.user_id
left join `group` g on ug.group_id=g.group_id;
From above query you may get blank values for some user's, who are not assigned to any group.
I don't see why a left join is necessary. Should be a regular join unless he wants to display users that don't have groups.
By the way, this is the perfect example of something that should be done in the DB with a select. Pulling everything from these tables and trying to sort through them in java is not a good idea. Maybe I read this post wrong though.
A subset of my database contains 3 tables
users
user_details
tasks
The main column of the user table is:
id {PK}
The user details table contains information about the users (only some users have these details, students). Thus the main columns of the users details table are:
user_id{PK,FK} | supervisor_id {FK}
The supervisor_id is an id in the users table. Each student has one supervisor.
Lastly, there is the tasks table where only students create tasks and the main columns of the tasks table are:
task_id{PK} | user_id{FK}
The problem I am having is getting a proper query for, if a supervisor wants to see all his students tasks. I know you can query all the students in the user_details table who have the supervisor's id. Then create another query where you select all the tasks whose user_id matches that of the first query performed.
This does not seem like a very efficient was to go about achieving this result. Are there better alternatives?
select ud.supervisor_id, ud.user_id, t.task_id
from user_details ud, users u
where ud.user_id = t.user_id
What you are looking for is a join. Instead of writing two separate queries to get the information, a join will allow you to connect the tables that you have in one query and get the information you need much faster.
Select *
From user_details ud
join tasks t
on ud.user_id = t.user_id
Where ud.supervisor_id = ?
The join essentially allows you to create one big table out of all of the columns of the tables you are using. The on keyword tells sql which values go together, so that you know all of the tasks belong to the student whose id matches the id that the supervisor has. Then, you can select whatever columns you like out of either table (as well as a lot of other fancy things).
I'm having trouble with a join query, my issue is as follows.
Table: battles
Fields: id,attacker_id,defender_id
Table: users
Fields: id,profile_image
I would like to do a query to retrieve a battle and get the profile images as well from the other table.
Is there a way to do this in a single or do I have to do more than one?
Thanks in advance.
I wanted to wait a while to see if you had any attempt or if you will answer my first question to know if I understood the problem. But maybe you don't have a starting point. Try something like:
SELECT
a.profile_image as attacker_profile_image,
d.profile_image as defender_profile_image
FROM
`battles` b
LEFT JOIN
`users` a
ON
b.`attacker_id` = a.`id`
LEFT JOIN
`users` d
ON
b.`defender_id` = d.`id`
the problem here is the fact that you need to join with the users table twice, so you will need to create aliases for the columns you plan to use
This query will fetch the two images only, you will need to add the extra fields
I'm trying to figure out the best approach, more specifically which JOIN to use, with my current situation:
I have two tables (entries, users) in my database. I'm querying and displaying all my news entries on one of my pages. With each entry, I'm also posting the entry information such as date, time and the author (or user) who created the entry.
In my "entries" table, I'm only inputting the user's id (user_id) as the post's author. The "users" table has all the author's information, such as name, email, etc.
Which "JOIN" statement would be best for specifically querying the "entries" table to display all my entries but to also grab certain information from my "users" table just by matching the user_id from "entries" to user_id in "users"?
Simple join statment
SELECT e.*,u.* FROM entries e JOIN users u
ON e.user_id = u.user.id
LEFT INNER JOIN probably.
it will display all from entries, and if users is atached to entries will be dispplayed aswell, else the field will be null.