I have the following tables and would like to query one more element from them.
categories table ->idcat(int), cat(varchar);
topics table ->idtopic(int), topic(varchar), idcat(int-fk), iduser(int-fk);
replies table ->idreply(int), reply(varchar) iduser(int-fk), idtopic(int-fk)
users table ->iduser(int), username(varchar).
My current query is;
$query = "SELECT t.topic, t.idtopic, u.username
FROM topics t
LEFT JOIN categories c ON t.idcat = c.idcat
LEFT JOIN users u ON t.iduser = u.iduser
WHERE c.idcat = '" . $idcat . "'";
Which presents 'Topic' and 'Username'. I'd like to show 'idReply' as well but don't know the proper JOIN syntax.
SELECT
t.topic,
t.idtopic,
u.username
FROM
topics t
LEFT JOIN
categories c ON t.idcat = c.idcat
LEFT JOIN
users u ON t.iduser = u.iduser
LEFT JOIN // new
replies r ON r.iduser = u.iduser AND r.idtopic = t.idtopic // new
WHERE c.idcat = '" . $idcat . "'";
This will generate a row for every reply to every topic in the specified category. Which could be a lot of records.
You may also want to experiment with the exact type of join on the replies table to get the result you want. LEFT JOIN is probably correct as you'll still get a result if there's no reply to a given topic. This may depend on your flavour of SQL.
OUTER JOIN & LEFT OUTER JOIN are possibilities.
Using INNER JOIN will ensure only topics with replies are returned.
You must have reply_id (foreign key) in your topics table. After that you can use this query.
$query = "SELECT t.topic, t.idtopic, u.username, r.id as reply_id
FROM topics t
LEFT JOIN categories c ON t.idcat = c.idcat
LEFT JOIN users u ON t.iduser = u.iduser
LEFT JOIN replies r ON t.reply_id = r.id
WHERE c.idcat = '" . $idcat . "'";
Related
I have 3 tables:
miners with columns id and name;
users with columns id, name and password;
user_miners with columns user_id and miner_id (foreign key to those other tables)
I need to print out users and their miner names
so for example i have user with id 1, and he has miners with names f,s,t
So i would need to print out:
1 f
1 s
1 t
how do i do that using left join?
I've tried all the possible left joins but i cant seem to get it working, maybe simply because i don't understand the concept of left join
('SELECT user_mineres.user_id, users.id, miners.name
FROM user_mineres
LEFT JOIN users
ON user_mineres.user_id=users.id
LEFT JOIN miners
ON users.id=miners.name
GROUP BY user_mineres.user_id ');
foreach ($stmt as $row)
{
echo $row['user_id'] . $row['name'] . "<br>";
}
i get errors that the column names are ambiguous or other syntax errors
You don't need a group by, only the proper joins and the proper ON clauses:
SELECT u.id, m.name
FROM users u
LEFT JOIN user_miners um ON um.user_id = u.id
LEFT JOIN miners m ON m.id = um.miner_id
I have 3 different tables I need to pull data from. What needs to happen is we pull posts from the posts table where the user who made the post is set as a public user, or if set as private, users they grant access to can view their posts.
Here are the tables:
user: id, username, name, password, email, private
posts: id, title, user, date, state
privateallowed: id, privateuser, alloweduser
and here is my code where I try to get the records:
$username = $_COOKIE['username'];
$sqlposts = "select p.id, u.id, u.private, a.privateuser, a.alloweduser from user u
inner join posts p on u.id = p.user
inner join privateallowed a on a.privateuser = u.id and a.alloweduser = " . $username . "
where u.private='public' or (a.privateuser=p.user and a.alloweduser=" . $username . ")";
$resultpost = mysqli_query($dbcon, $sqlposts);
$numrows = mysqli_num_rows($resultpost);
Unfortunately, no records are being returned. Any help or ideas are appreciated.
For what it's worth (#pgngp commented about needing single quotes around '" . $username . "'):
$username = $_COOKIE['username'];
$sqlposts = "SELECT p.id, u.id, u.private, a.privateuser, a.alloweduser
FROM user u
INNER JOIN posts p ON
u.id = p.user
INNER JOIN privateallowed a ON
a.privateuser = u.id AND a.alloweduser = '" . $username . "'
WHERE u.private='public';
$resultpost = mysqli_query($dbcon, $sqlposts);
$numrows = mysqli_num_rows($resultpost)";
Also note, I've removed the following from your WHERE condition because it is redundant due to previous INNER JOIN's. We can only infer this because you've used INNER JOIN, had you used LEFT JOIN you would need to leave the condition in as-is.
. . .or (a.privateuser=p.user and a.alloweduser=" . $username . ")"
Explanation:
INNER JOIN posts p ON u.id = p.user
So we have determined that u.id = p.user
INNER JOIN privateallowed a ON a.privateuser = u.id
So we infer that a.privateuser = p.user
AND a.alloweduser = '" . $username . "'
This covers the remaining condition in your WHERE
I did find an answer, though I'm sure it isn't a perfect one. What I did was I broke the statements into separate select statements, and then embed one in the where clause, as follows:
$sqlposts = "SELECT p.id, u.id, u.private
FROM user u
INNER JOIN posts p ON u.id = p.user
WHERE u.private='public' or p.user in
(
select a.privateuser
from privateallowed a
inner join posts p on p.user = a.privateuser
where a.alloweduser=" . $username . "
)";
Me and another person who is pretty good with sql looked at this for a couple of hours, and we just couldn't get the select to return the correct results. We tried the following, but it returned each public user 3 times for some reason:
SELECT p.id, u.id, u.private
FROM user u
INNER JOIN posts p ON u.id = p.user
INNER JOIN privateallowed a on a.alloweduser=24
WHERE u.private='public' or p.user = a.privateuser
I appreciate everyone's help on this. If anyone has any other ideas, I appreciate them. I'm working on a web site that I am hoping will grow, and I want to make sure the page loads as fast as possible.
First is a user table, second a places table and third a favorites table (having two fk, one from user and another from places). I want to get all the favorite places of one user, how do I do that?
I tried to play around with joins but what I don't know is how to get data of a particular user.
$qry =
"SELECT places.place_id , places.db_image ,places.description from places
inner join favorites on places.place_id = favorites.place_id
inner join user on user.id = favorites.user_id
";
$query=mysqli_query($con ,$qry);
$return_arr = array();
$sql = sprintf(
'SELECT
p.place_id,
p.db_image,
p.description
FROM
places p INNER JOIN
favorites f ON p.place_id = f.place_id INNER JOIN
user u ON u.id = f.user_id
WHERE
u.id = %d'
, $userId);
or if you want simply select all columns from places
SELECT
p.*
FROM
places p INNER JOIN
favorites f ON p.place_id = f.place_id INNER JOIN
user u ON u.id = f.user_id
WHERE
u.id = %d
It is better to use prepared statements, but if you are not familiar with them, this is good enough.
I have PHP website with a table that prints out search results from a MySQL database via form with an input box. I use this SQL syntax and it works fine. I can search in one filed to get results from location.room_name and users.user_name:
SELECT:
SELECT computers.*, location.room_name AS location
FROM computers
LEFT JOIN location ON computers.location = location.id
LEFT JOIN users ON computers.user_1 = users.id".
" ".$searchCriterias."
ORDER BY id
WHERE:
$searchCriterias =
"WHERE
location.room_name LIKE '%".$s."%' OR
users.user_name LIKE '%".$s."%'
";
$s is the string from the search form.
The thing is that I have computers.user_1, computers.user_2 and computers.user_3 that all corresponds to users.id as in the syntax above. When I search for a username I would like to match it with user_1, user_2 and user_3 but I don't get it to work. I can only match it with one (in this case user_1).
I have tried to add LEFT JOIN users ON computers.user_2 = users.id and gets this error message: Not unique table/alias: 'users'
and...
LEFT JOIN users AS u1 ON computers.user_1 = users.id for all three and gets this messge: Unknown column 'users.id' in 'on clause'.
Why doesn't it work?
As you said you have 3 columns in computers table then try following while join. Also added GROUP BY to get unique result per user.
$query = "SELECT computers.*, location.room_name AS location
FROM computers
LEFT JOIN location ON computers.location = location.id
LEFT JOIN users ON (computers.user_1 = users.id
OR computers.user_2 = users.id
OR computers.user_3 = users.id ) ".
$searchCriterias . " GROUP BY users.id ORDER BY id";
Change your ON condition to IN statement :
SELECT computers.*, location.room_name AS location
FROM computers
LEFT JOIN location ON computers.location = location.id
LEFT JOIN users
ON ((users.id = computers.user_1) or
(users.id =computer.user_2 and not exists(select 1 from users t where t.id = computers.user_1)) OR
(users.id = computer.user_3 AND not exists(select 1 from users p where p.id IN(computer.user_2,computer.user_1))))".
" ".$searchCriterias."
ORDER BY id
Another option is to join against users 3 times, and amend your WHERE clause to check against 3 different tables.
Might need a DISTINCT to remove duplicates as I presume names can match multiple times.
This has the advantage over using an OR in the ON clause that it can still use indexes for the joins.
SELECT computers.*, location.room_name AS location
FROM computers
LEFT JOIN location ON computers.location = location.id
LEFT JOIN users users1 ON computers.user_1 = users1.id
LEFT JOIN users users2 ON computers.user_2 = users2.id
LEFT JOIN users users3 ON computers.user_3 = users3.id".
" ".$searchCriterias."
ORDER BY id
And the WHERE clause
$searchCriterias =
"WHERE
location.room_name LIKE '%".$s."%' OR
users1.user_name LIKE '%".$s."%' OR
users2.user_name LIKE '%".$s."%' OR
users3.user_name LIKE '%".$s."%'
";
I currently have a database with 12 tables. I am doing a php query to pull the information from the database but I am not getting anything displayed. The query alone bridges all the tables starting with table schedule that have a foreign key related. Should I need to start the query from the table class and bridge with other tables?
TABLE DESIGN- PICTURE
If you like to duplicate my design- QUERY
$query = ("SELECT class_name, class_caption, class_credit_hours, class_description
FROM schedule
INNER JOIN section
ON class.id = section.class_id
INNER JOIN faculty
ON faculty.id = section.faculty_id
INNER JOIN faculty
ON faculty.id = office_hours.faculty_id
INNER JOIN faculty_titles
ON faculty_titles.faculty_id = faculty.id
INNER JOIN faculty_education
ON faculty_education.faculty_id = faculty.id
INNER JOIN section
ON section.faculty_id = faculty.id
INNER JOIN class
ON class.id = section.class_id
INNER JOIN major_class_br
ON major_class_br.class_id = class.id
INNER JOIN major_minor
ON major_class_br.major_minor_id = major_minor.id
");
//execute query
$result = mysql_query($query);
if ($result){
$totalhours = 0;
while ($row = mysql_fetch_assoc( $result ))
{
print "<b>" . $row['class_name'] . "</b><br>";
print $row['class_caption'] . "<br>";
print $row['class_description'] . "<br>";
print $row ['class_credit_hours'] . "hrs. <br>";
print "------------------------------<br />";
$totalhours += $row['class_credit_hours'];
}
}
SQL fiddle query
SELECT class_name, class_caption, class_credit_hours, class_description
FROM schedule
INNER JOIN section
ON class.id = section.class_id
Right here there's a problem: you are doing a INNER JOIN using the field 'class.id' but the table 'class' isn't in either side of the JOIN. So it won't work.
The query should start like this:
SELECT class_name, class_caption, class_credit_hours, class_description
FROM class
INNER JOIN section
ON class.id = section.class_id
And then do the JOIN with the table 'schedule' with the table it shares a common index (I guess it would be class).
The complete query should be something like this:
SELECT class.class_name, class.class_caption, class.class_credit_hours, class.class_description
FROM class
INNER JOIN section
ON class.id = section.class_id
INNER JOIN faculty
ON faculty.id = section.faculty_id OR faculty.id = office_hours.faculty_id
INNER JOIN faculty_titles
ON faculty_titles.faculty_id = faculty.id
INNER JOIN faculty_education
ON faculty_education.faculty_id = faculty.id
INNER JOIN major_class_br
ON major_class_br.class_id = class.id
INNER JOIN major_minor
ON major_class_br.major_minor_id = major_minor.id
INNER JOIN sched_sect_br
ON sched_sect_br.section_id = section.id
INNER JOIN schedule
ON schedule.id = sched_sect_br.schedule_id
INNER JOIN semester
ON semester.id = schedule.semester_id
INNER JOIN office_hours
ON schedule.id = office_hours.schedule_id AND faculty.id = office_hours.faculty_id
This query gets info from all the tables you have in your graph, aside from the event table, that isn't related to any other. But still this query should have more fields on the SELECT (you are only selection fields from the class table, I understand you'd want data from the other 10 tables as well), to do this simple add 'tablename.field' to the list of fields from the SELECT.