I am trying to combine 2 tables from my database:
files table:
id
file_name
file_description
file_url
access_files table:
id
student_id
file_id
Here is my sql code, currently getting all files from the files table, it doesn`t show the selected files for the user.
<?php
$SQL = "SELECT * FROM files, access_files WHERE student_id ='$studentid'";
$result = mysql_query($SQL);
while ($db_field = mysql_fetch_assoc($result)) {
?>
<div class="accordion-group">
<div class="accordion-heading">
<a href="#<?php print $db_field['file_id']; ?>" data-parent="#accordion" data-toggle="collapse" class="accordion-toggle collapsed">
<?php print $db_field['file_name']; ?>
</a>
</div>
<div class="accordion-body collapse in" id="<?php print $db_field['file_id']; ?>">
<div class="accordion-inner">
<?php print $db_field['file_description']; ?><br/><br/>
Download File Now!
<br/><br/>
</div>
</div>
</div>
<?php } ?>
The code is suppose to show only the files associated to the user.
What you need to do is JOIN the tables.
Most common types of JOINs:
INNER JOIN - Used to match data where it can match the ON () statement. If the ON() doesn't match, the result will be excluded.
LEFT JOIN - Used if the data you match in the ON() doesn't have to be there. It just appends the data to the original FROM, and fills columns with NULL if no data is matched.
Example
SELECT
ft.id,
ft.file_name,
ft.file_description,
ft.file_url,
af.id as access_id,
af.student_id,
af.file_id
FROM
files ft
INNER JOIN access_files af ON ( ft.id = af.file_id )
WHERE
fa.student_id = '$studentid'
You are making a classic cartesian join with your query:
SELECT * FROM files, access_files WHERE student_id ='$studentid'
You need to specify how the two tables are connected:
SELECT * FROM files a, access_files b WHERE a.student_id ='$studentid' and b.studentID=a.student_id
If you don't specify the link - or don't have one, the database will try to link every single row in the first table with every single row in the second.
Join your tables.
SELECT table1.*, table2.*
FROM table1
LEFT JOIN table1.pk = table2.fk
WHERE table1.pk = 1;
Related
I am struggling with my code. I try to make a News Feed.
The news feed is working well but now I want to add a avatar picture on each news row to have a picture from the author. The avatar picture path is in a different table (users).
That means I need to get in the loop the specific user ID ($row['uid']) and with that uid I need to get the related path from the user's avatar in the user table.
If I try to use a query in my loop it shows me only one result instead of 6 as specified in my query.
Do you have any suggestion or advise how I can solve that issue?
Many thanks for your support!
This is my attempt for the moment:
<div class="timeline p-4 block mb-4">
<?php
// Getting the user id and the feedmessage from Table "activity_feed"
$statement = $pdo->prepare("SELECT feed_message, uid FROM activity_feed WHERE cid = :cid ORDER BY id DESC LIMIT 6");
$result = $statement->execute(array('cid' => $cid));
$count = 1;
while($row = $statement->fetch())
{
// Starting the News feed Loop
?>
<?php
// This will repeat now X times as defined in the query above by = LIMIT ?
// Getting the avatar path from the user table
$statement = $pdo->prepare("SELECT avatar FROM users WHERE id = :id");
$result = $statement->execute(array('id' => $row['uid']));
$user_avatar = $statement->fetch();
?>
<style>
#circle_feed {
height:50px;
width:50px;
border-radius:50%;
/* Including the avatar path from query above*/
background-image: url("<?php echo $user_avatar['avatar']; ?>");
background-position:center;
background-size:cover;
}
</style>
<div class="tl-item ">
<div class="tl-dot"><a class="tl-author" href="#" data-abc="true">
<!-- Including the Avatar circle here-->
<span class="w-40 avatar circle gd-warning border" id="circle_feed"></span></a>
</div>
<div class="tl-content">
<div class=""><?php echo $row['feed_message']; ?></div>
<div class="tl-date text-muted mt-1">DATE</div>
</div>
</div>
<?php
// News Feed Loop is ending here
}
?>
</div>
</div>
There is no need to loop. SQL is a set-based language that can give your the results that you want in a single query, using the join syntax:
SELECT
af.feed_message,
af.uid,
u.avatar
FROM activity_feed af
INNER JOIN users u ON u.id = af.uid
WHERE af.cid = :cid
ORDER BY af.id DESC
LIMIT 6
This is much more efficient than running 7 queries (one for the activity feed, then one for each row returned by the first query, in a PHP loop).
You can then fetch the rows of the resultset and use this directly in your application.
I have two tables in my database by name language and language_variables.
In language table, I have stored languages and in language_variables have value of specific word in all languages.
DB Structure & data of language
id, title, short_code, type enum('ltr', 'rtl'), default enum('yes', 'no'), status enum('on', 'off')
1, English, en, ltr, yes, on
2, Urdu, ur, rtl, no, on
DB Structure & data of language_variables
id, language_id, keyword, value
1, 1, str_word, this is simple string
2, 2, str_word, اس سادہ سلک ہے
3, 1, str_word2, this is 2nd string
Output I want
I want to show keyword str_word for once and show drop down list of languages list for same keyword.
Issue in my output
My SQL query is
SELECT
lv.id, lv.language_id, lv.keyword, lv.`value`, l.title
FROM language_variable AS lv
INNER JOIN `language` AS l ON l.id = lv.language_id
GROUP BY lv.keyword
ORDER BY lv.id DESC
My view
<?php
foreach($records as $record)
{
?>
<div class="banner-row1">
<div class="banner-row-text">
<h2><?=$record->keyword?></h2>
<p class="text-muted">
<small>
Value: <?=$record->value?><br />
Languages:
<select id="language_id" required>
<option></option>
<?php
foreach($languages as $language)
{
echo '<option value="'.$record->id.'">'.$language->title.'</option>';
}
?>
</select>
</small>
</p>
</div>
<div class="clr"></div>
</div>
<?php
}
?>
You should join with language_id, not with id in language_variables table.
INNER JOIN `language` AS l ON lv.id = l.id
Use this
INNER JOIN `language` AS l ON l.id = lv.language_id
^ ^
You need to do at least 2 queries (or change your whole code).
1) get all the "str_word" : query1 = select distinct keyword from language_variable
2) get all the values : query2 = select * from language_variable
3) do a foreach loop with query1, and inside it, display all the corresponding values str_word.
That solution requires to have the query2 as an associative array indexed on str_word.
The alternative, easier to code but requiring more resources is to do the query1 then, in the loop, do the corresponding query select * from language_variable where str_word=:that_keyword (that means as many sql query as there is keywords)
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";
I have 2 mysql tables named
blog
comment
What i am trying to do to retrieve following columns
user_name comment_desc from the comment table using blog_id.
Both the tables have blog_id in common.
here below are the screenshots of both sql tables
Comment Table:
Blog Table:
I tried the query this way.
SELECT blog.blog_id, comment.user_name, comment.comment_desc
FROM
blog (b)
INNER JOIN
comment (c)
ON b.blog_id = c.blog_id
i dont have access to upload the image thats why i uploaded to photobucket.
The PHP Code....
<?php
$comments_set = blog_comments();
var_dump($comments_set);
while($comments_all = mysql_fetch_assoc($comments_set)){
$name = $comments_all['user_name'];
$desc = $comments_all['comment_desc'];
echo
"<ol class=\"commentlist clearfix\">
<li class=\"comment even thread-even depth-1\" id=\"li-comment-1\">
<div id=\"comment-1\" class=\"comment-wrap clearfix\">
<div class=\"comment-meta\">
<div class=\"comment-author vcard\">
<span class=\"comment-avatar clearfix\">
<img alt='' src='http://0.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s=60' class='avatar avatar-60 photo avatar-default' height='60' width='60' /></span>
</div>
</div>
<div class=\"comment-content clearfix\">
<div class=\"comment-author\">$name<span>January 24, 2013 at 10:46 am · <a class='comment-reply-link' href=\"#\">Reply</a></span></div>
<p>$desc</p>
</div>
</div>
</li>
</ol>
";
}
?>
You need user_name and desc from comment table with blog_ig
Why you need to join these 2 tables then ? you could retrieve information from comment table by blog id
select * from comments where blog_id='blog_id'
You are using alias so at the time of SELECT statement, specify it through alias name. You need to remove parenthesis around alias name...
SELECT b.blog_id, c.user_name, c.comment_desc
FROM
blog b
INNER JOIN
comment c
ON b.blog_id = c.blog_id
I think you have incorrectly define the blog_id columns. Please check columns' datatype and sizes.
It will fail when joining tables.
If you can paste error it will be more helpful
Thanks.
I think you should go for Left Join because may be you want to have blogs to be displayed whether they have comments or not.
SELECT b.blog_id, c.user_name, c.comment_desc
FROM
blog as b
LEFT JOIN
comment as c
ON b.blog_id = c.blog_id
So I have two tables, article and comments (which has one-to-many relationship (1 article - many comments)). This is how the table is structured:
Articles - id (prikey), title, publicationDate, content
Comments - com_id (prikey), author, comment, id (foreign key)
I used this to query the two tables:
SELECT * FROM articles as a INNER JOIN comments as c ON a.id = c.id
Previously, I was only displaying the articles table using this:
<?php
while($row = mysqli_fetch_array($query)) {
echo "
<div id='article'>
<header>
<hgroup>
<h2>".$row['title']."</h2>
<h4>Posted on ".$row['publicationDate']."</h4>
</hgroup>
</header><p>".$row['content']."</p></div>";
}
?>
This displays all articles (with date, title, content, etc.). Now there are comments. How do I edit the php code (or if my query is incorrect, how to write the query), so that it shows all articles and all comments per article as in:
Article One
-- Comment 1
-- Comment 2, etc.
Article Two
-- Comment 1
-- Comment 2, etc.
An alternative would be to split the query into two.
The first would bring back the articles you want...
SELECT * FROM article;
Once you have those, you can get all the IDs and use something like the following
SELECT * FROM comments WHERE article_id IN (".$list.");
This restricts the MySQL queries to 2 whilst getting all the data you need. After this loop around the article data, and in that loop, loop around the comments data.
This also means that, unlike using GROUP_CONCAT, you will also have author data to use.
It's not a very eloquent solution, but should work.
Query:
SELECT c.author, c.comment,
a.id article_id, a.title, a.publicationDate, a.content
FROM comments c
RIGHT JOIN articles a
ON c.id = a.id
PHP:
<?php
$lastArticleId = 0;
$isNewArticle = false;
while($row = mysqli_fetch_array($query)) {
$isNewArticle = ($lastArticleId != $row['article_id']) ? true : false;
if($isNewArticle) {
$lastArticleId = $row['article_id']; ?>
<div class="article">
<header>
<hgroup>
<h2><?php echo $row['title']; ?></h2>
<h4>Posted on <?php echo $row['publicationDate']; ?></h4>
</hgroup>
</header>
<p><?php echo $row['content']; ?></p>
</div>
<?php
}
if($row['comment'] != '') { ?>
<p><strong><?php echo $row['author']; ?></strong> - <?php echo $row['comment']; ?></p>
<?php
} ?>
<?php
} ?>
Use something like
SELECT a.article
,GROUP_CONCAT(CONCAT('<p>', c.comment, '</p>') SEPARATOR "\n") as comments
FROM
article a
INNER JOIN comment c ON (c.article_id = a.id)
WHERE a.id = '12454';
You may have to fiddle a bit with the separator.
See: http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat
Do note however:
The result is truncated to the maximum length that is given by the group_concat_max_len system variable, which has a default value of 1024. The value can be set higher, although the effective maximum length of the return value is constrained by the value of max_allowed_packet. The syntax to change the value of group_concat_max_len at runtime is as follows, where val is an unsigned integer:
SET [GLOBAL | SESSION] group_concat_max_len = val;
See here how to change max_allowed_packet
http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_max_allowed_packet
Look into MySQL GROUP_CONCAT which will return a comma delimited list of items. You can then explode that for your comments section.
once a person will comment on a article insert article id with that comment and later get them accordingly something like this
once a person will select an article to read send article id in the $_GET to your article page so you can excess the article id.Once a person will comment on that article insert it as follows
$sql = mysql_query("INSERT INTO comments_table (subject,article_id,comments) VALUES ('$subject','$_GET['id']','$comments')");
and later when you pulling them do it the same way as you have the article id in the $_GET
you can access it run a query like this
$fetch = mysql_query("SELECT * FROM comments WHERE article_id = $_GET['id'] ORDER BY id DESC") or die(mysql_error());
Hope this will work