Inner join doesn't work with PDO and fetch assoc - php

For my news en post comment system I can't get the query get results from 2 tables (tbl_news and tbl_comments). In another program I made with mysqli the inner join worked but now this time with PDO I can't get it to work.
This is my code:
$newsQuery = $db->prepare("SELECT *
FROM tbl_news
INNER JOIN tbl_comments ON tbl_news.news_id = tbl_comments.news_id
ORDER BY news_id DESC
LIMIT 5");
$newsQuery -> execute();
while($newsFetch = $newsQuery->fetch(PDO::FETCH_OBJ)) {
echo "<div class='news-post'><h3 class='post-title'>" . $newsFetch->title . "</h3>
<p style='float:left'>By: <span class='post-author'>" . $newsFetch->author . "</span></p>
<p style='float:right'>Date: <span class='post-date' style='font-style:italic;'>" . $newsFetch->date . "</span></p>
<br><p>" . $newsFetch->text . "</p></div>";
if(isset($_SESSION['user']) && ($newsFetch->comments == '1')) {
echo "Comments(";
echo "<div id='commentClick'>Click <a href='#' id='openForm'>here</a> to post a comment</div>";
echo "<form class='navbar-form' id='commentForm'><input style='margin-right:5px' type='text' size='80%' name='commentText' placeholder='Type your comment here'><input type='submit' class='btn btn-primary btn-xs' value='Send'></form>";
}elseif(!isset($_SESSION['user']) && ($newsFetch->comments == '1')) {
echo "Click here to view comments. If you want to post comments please login first";
}else{
echo "Comments are disabled for this news item";
}
}
In the database I have the following values:
in tbl_news there is a news_id and in tbl_comments are comment_id, news_id and user_id.
Thanks in advance!

You need to use alias for your database table names, ex:
SELECT n.*, c.* FROM tbl_news n
INNER JOIN tbl_comments c ON n.news_id = c.news_id
ORDER BY n.news_id DESC LIMIT 5

Your inner join query should be like this
SELECT Customers.CustomerName, Orders.OrderID
FROM Customers
INNER JOIN Orders
ON Customers.CustomerID=Orders.CustomerID
ORDER BY Customers.CustomerName;
I mean you need to specify the tablename.columnname instead of using all (*)
EDIT
1052 Column 'news_id' in order clause is ambiguous'
This error happens when you are joining 2 or more tables in a statement and there are columns among these tables that have the same name and you didn’t prefix the column name with the table name when referencing the column in your statement.

Related

How can i join Three tables and Create a table using Select statement

I have three table in Mysql database MIITEM, DEMAND, MIILOC tables i want to select field from these three table display as a table .
i tried this but the join doesnt work for me
$sql = "SELECT demand.itemid, demand.qty, MIITEM.descr FROM demand
INNER JOIN MIITEM ON MIITEM.itemId = demand.itemid
WHERE demand.itemid = MIITEM.itemId
ORDER BY demand.itemid DESC";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "id: " . $row["itemid"]. " - demand: " . $row["qty"]. " - sales: " . $row["sales"]. "<br>";
}
} else {
echo "0 results";
}
$conn->close();
select dt.*, three_table.* from (
SELECT demand.itemid, demand.qty, MIITEM.descr FROM demand
INNER JOIN MIITEM ON MIITEM.itemId = demand.itemid
ORDER BY demand.itemid DESC) as dt inner join three_table on (dt.itemid = three_table.itemid)
you create the first select inner join 2 table wrap it with new select and inner join with the last table,
i didn't check the code... also you dont need the "where" you already doing inner join...

Query inside of another query?

I've searched and found ways to do queries inside queries, but I have not found the right answer.
What I am trying to do is to fetch comments from the table called users_profiles_comments and by doing that I will get the field of '.$member["author"].'. Then I want to show who made the comment with their rank and a display picture.
But because there is no user details stored in the comments table because its for comments, I need to create a query inside of my query result where I can have this:
"SELECT * FROM users WHERE username = $member['author'] ORDER BY `id` ASC"
The '.$member["author"].' value comes from the main query but I need it so it can find fields in my users table.
$sql = "SELECT * FROM users_profiles_comments WHERE postid = '1' ORDER BY `id` ASC";
$stm = $dbh->prepare($sql);
$stm->execute();
$users = $stm->fetchAll();
foreach ($users as $row) {
print '
<img src="'.$member["profilepic"].'" style="float:left;margin-right:10px;" width="80px" height="85pxm">
<h4>'. $row["author"] .'
<small>'. $row["date"] .'</small>
</h4>
<p>'. $row["content"] .'</p><hr> </a></li>';
}
echo '
</div>
';
I hope you understand.
Edit:
The database.
users Table
http://img855.imageshack.us/img855/4387/qyjl.png
users_profiles_comments table
http://i.imgur.com/aKRF5MN.png
But because there is no user details stored in the comments table because its for comments
This is good. You do not want to have your database information duplicated in both tables (de-normalized data) - there is no need.
Generally a foreign key is added to inverse side of the relationship. This would mean you have a user_id column within your comments table, allowing you to select the data in one query using a JOIN
SELECT comment.*, user.name AS comment_author
FROM comment
INNER JOIN user ON user.id = comment.user_id
WHERE user.id = 123
Edit - I flipped to JOIN to return comments rather than users, (as you said "to fetch comments") however both ways will work, it just depends which side of the relationship you are on.
Edit 2 To respond to your comment;
How would I be able to show this on my PHP code on the result?
you can be more specific with the above query (not use *) and render it as follows :
$sql = "
SELECT
comment.`date` as comment_date,
comment.content,
user.name AS author_name,
user.profilepic as author_pic
FROM
users_profiles_comments as comment
INNER JOIN
user ON user.id = comment.user_id
WHERE
comment.postid = 1
";
//...
$comments = $stmt->fetchAll();
foreach ($comments as $comment) {
echo '<img src="' . $comment['author_pic'] . '"/>';
echo '<h4>' . $comment['author_name'] . '<small>' . $comment['comment_date'] .'</small></h4>';
echo '<p>' . $comment['content'] . '</p>';
}
You can select member name in SQL statement. You can try this query, this query will bring all the information from two table if users.username = users_profiles_comments.author
WAY 1:
SELECT t1.*, t2.* FROM
(
SELECT * FROM users WHERE username = '.$member["author"].' ORDER BY `id` ASC
) AS t1
LEFT JOIN
(
SELECT * FROM users_profiles_comments WHERE postid = '1' ORDER BY `id` ASC
) AS t2
ON t1.username = t2.author
Finally, do your foreach to print
===================================================================
WAY 2:
You can try this also-
SELECT *,
(SELECT profilepic FROM users WHERE users.username = users_profiles_comments.author) AS profilepic
FROM users_profiles_comments WHERE postid = '1' ORDER BY `id` ASC
And print profilepic using $row['profilepic'] in your foreach loop
=====================================================================
WAY 3:
SELECT t1.*, t2.* FROM
(
SELECT * FROM comments WHERE postid = '1'
) AS t1
LEFT JOIN
(
SELECT * FROM users
) AS t2
ON t1.author = t2.username
What I understand is that you need to get information about the user from another table called user_profile_comments, based on the user id (correct me if wrong: :-)). Use a left outer JOIN to fetch data from another table, limited on user id.
See http://www.w3schools.com/sql/sql_join.asp for more info.

Mysql query returning too many rows

so I have 3 tables all inner joined, I am trying to put discussions with the discussion topic on my main page, with the users name and the latest discussion message on the main page as well.
THE PROBLEM: The query is returning all messages attached to all the discussions.....I just need the last message associated with the discussion returned.
I have been at this all day and cant figure it out. I have tried group by but that just gave me an error on mysqli_fetch_array
Here is my code
$discussionquery = "SELECT discussion_messages.discussion_id, user_profile.first_name, user_profile.last_name, discussion_messages.message_text, case_discussion.discussion_title
FROM `user_profile`
INNER JOIN discussion_messages
ON (user_profile.user_id = discussion_messages.user_id)
INNER JOIN case_discussion
ON (case_discussion.discussion_id = discussion_messages.discussion_id)
WHERE discussion_messages.case_id = '$thecaseid'
ORDER BY discussion_messages.message_id DESC";
$discussionquerydata = mysqli_query($dbc, $discussionquery);
while ($row2 = mysqli_fetch_array($discussionquerydata)) {
$discussion_id = $row2['discussion_id'];
?>
<!-- Begin Recent Discussions -->
<div class="row">
<a href="discussion.php?newfact=$thecaseid'>">
<div class="col-xs-4 col-md-2">
<img src="img/client4.jpg" class="profile_picture img-rounded">
<?php echo '<h6 class="discussionname">' . $row2['first_name'] . ' ' . $row2['last_name'] . '</h6>';?>
</div>
</a>
<div class="col-xs-8 col-md-10 discussion_title">
<?php echo '<h5> '.$row2['discussion_title'].' -'. $row2['message_text'];?></h5>
<h6 class="pull-right">Dec. 25</h6>
</div>
</div>
<?php
};
You need logic to find the last message for each discussion. There is more than one way to write this condition.
The following does it using a not exists clause. This checks that there are no messages with a larger id for the discussion:
SELECT dm.discussion_id, up.first_name, up.last_name, dm.message_text, cd.discussion_title
FROM `user_profile` up INNER JOIN
discussion_messages dm
ON (user_profile.user_id = dm.user_id) INNER JOIN
case_discussion cd
ON (cd.discussion_id = dm.discussion_id)
WHERE dm.case_id = '$thecaseid' and
not exists (select 1
from discussion_messages dm2
where dm2.discussion_id = dm.discussion_id and
dm2.message_id > dm.message_id
)
ORDER BY dm.message_id DESC;
One suggestion, use table aliases. The amount of total code will be smaller and easier to understand. Use the limit clause to return 1 row.
$discussionquery = "
SELECT
m.discussion_id,
u.first_name,
u.last_name,
d.message_text,
c.discussion_title
FROM `user_profile` as u
INNER JOIN discussion_messages as m
ON (u.user_id = m.user_id)
INNER JOIN case_discussion c
ON (m.discussion_id = c.discussion_id)
WHERE
m.case_id = '$thecaseid'
ORDER BY
m.message_id DESC
LIMIT 1";

List IDs That Aren't in An Inner Join

I have a SELECT statement that provides me with a list of relevant IDs and company names that match the criteria. Here is the statement:
$result = mysqli_query($con,"SELECT a.OWNER_ID,b.ID, b.TITLE AS companyname FROM b_crm_act a INNER JOIN b_crm_company b ON a.OWNER_ID = b.ID");
while($row = mysqli_fetch_array($result))
{
echo "<tr>";
echo "<td>" . $row['ID'] . "</td>";
echo "<td>" . $row['companyname'] . "</td>";
echo "</tr>";
}
echo "</table>";
This lists all the IDs and company names. What I actually need is a list of IDs from b_crm_company that aren't in b_crm_act. I'm thinking I use NOT IN function but I've tried this and it's not listing anything.
Your help would be appreciated.
you can use LEFT JOIN on this
SELECT a.ID,
a.TITLE AS companyname
FROM b_crm_company a
LEFT JOIN b_crm_act b
ON a.ID = b.OWNER_ID // <== specify how the tables are linked
WHERE b.OWNER_ID IS NULL // <== a value of NULL when it doesn't exists
Not sure about your column names but this is how it looks like.
I don't know how efficient this is but have you tried using a NOT IN subquery?
SELECT ID,title FROM b_crm_company WHERE ID NOT IN( SELECT ID FROM b_crm_company INNER JOIN b_crm_act ON b_crm_act.OWNER_ID = b_crm_company.ID )

How to reference another table with a consistent primary key across tables

I have two tables which both have a unique PID. I need to know how I should setup the primary/foreign keys so I can access fields from both tables in one SQL statement.
For example: With the following data structure i'd like to echo out the players name and photo but also echo out all their stats via PHP as well. I have successfully done this with just the player Stats, but I do not know how to get access to fields in another table.
Here is my database structure so far:
Players
-PID (Set as Primary Key)
-Name
-Height
-College
-Photo
Stats
-PID
-Touchdowns
-Receptions
Current PHP Code:
$query="
SELECT * FROM Stats
ORDER BY Stats.FantasyPoints DESC";
$res=mysql_query($query);
$num=mysql_numrows($res);
$i=0;
while($i< $num){
$Name = mysql_result($res, $i, "Name");
$FantasyPoints = mysql_result($res, $i, "FantasyPoints");
echo $Name . ': '. $FantasyPoints . "<br />";
$i++;
}
$sql = "
SELECT p.*, s.*
FROM Players AS p
LEFT JOIN Stats AS s ON p.PID = s.PID
ORDER BY s.FantasyPoints DESC
";
You could also use a JOIN rather than a LEFT JOIN which would limit the result to only players who have stats
Edited sql to produce result similar to your own sql.
======================================================
This is how I would go about it...
$query =
"
SELECT s.*, p.*
FROM Stats AS s
LEFT JOIN Players AS p ON p.PID = s.PID
ORDER BY s.FantasyPoints DESC
";
$res = mysql_query($query);
while ($row = mysql_fetch_assoc($res))
{
echo "{$row['name']}: {$row['FantasyPoints']}<br />";
}

Categories