forumcats: id, name
forums: id, name, cat_id
How can i join these together and print the forums assigned to the categories under them
Would really appriciate if someone could give me a hand
This is what i mean:
A category
A forum<
A forum
A 2nd category
Another forum
Another forum
Another forum
A 3rd catagory
Another forum
Another forum
Another forum
$reslt = mysql_query("select id, name, cat_id from forums");
while ($row=mysql_fetch_assoc($reslt)) {
echo "<h1>Category here</h1<";
echo "<h3>$row[name]</h3>";
}
You want this query:
SELECT forums.*, forumcats.name AS category_name
FROM forums
INNER JOIN forumcats ON (forums.cat_id = forumcats.cat_id)
Then when you loop through the results, you want to identify when you've moved on to a new category. For example:
$last_cat_id = null;
while ($row=mysql_fetch_assoc($reslt)) {
if ($last_cat_id != $row['cat_id']) {
echo '<h1>' . $row['category_name'] . '</h1>';
$last_cat_id = $row['cat_id'];
}
echo "<h3>$row[name]</h3>";
}
Related
Afternoon All,
Looking for some direction with listing posts by category.
I have begun coding a CMS (as a PHP beginner) and up until now all was going well.
I have made a link to pre-set categories (Category 1, Category 2 etc etc)
I also have a categories table with ID and Category name.
A table for users posts with CatID and category name in it as well
I'm guessing I would need to join tables to be able to list any posts in specific category (Select Cat 1 to see all Cat 1 posts. Same for Cat 2, 3 etc etc)
When a user adds a post it fills the category name in users posts table but I get no CAT ID and nothing added into categories table so how do i call on this to display categorised posts?
I have a feeling I am probably thinking to much into things and over-complicating what should probably be simple to do.
Ihe code i have at the moment (see below) has no effect at all?
Please help point me in the right direction, I have tried everything.
Many thanks to all in advance
CODE:
$catSql ="SELECT ID, Category
FROM categories
LEFT JOIN users_posts
ON CatID, category, BlogID";
$catQry = mysqli_query($link, $catSql);
while ($row = mysqli_fetch_assoc($catQry)){
if($row['category_name'] != $lastCategory)
{
$lastCategory = $row['category'];
echo "<br /><strong>$lastCategory</strong>";
}
echo $row['category'] . ' <br />';
}
Your SQL is wrong I think this should work
$catSql = "SELECT *
FROM categories
LEFT JOIN users_posts
ON categories.ID = users_posts.CatID";
Your SQL for listing posts could check to see if a categoryID exists in the URL, and if it does, use it to filter the results.. Then, you would just need to create some links to the same page to add the required category id to the URL.
<a href='?cat=1'>Cat 1</a> | <a href='?cat=2'>Cat 2</a> | etc..
SQL
$sql = "SELECT * FROM POSTS";
if(isset($_GET['cat'])){
$catID = (int)$_GET['cat']; //or something similar
$sql .= " LEFT JOIN category USING categoryID WHERE categoryID = $catID";
}
I try to achieve the following:
Some great post title (posted in Sport)
Another title of a post here (posted in Space)
Cool title of some post (posted in Technologies)
And so on...
I display all posts from all categories and put the category name next to each post.
I do not understand where and why fail. All posts are multiplied by the number of categories.
Here is what I have till now:
posts table:
post_id
post_title
post_content
category_id
categories table:
category_id
category_name
category_description
And my queries and PHP code:
// I select all categories with their id and name
$stmt = $db->prepare("SELECT * FROM categories");
$stmt->execute();
$row_categories = $stmt->fetchAll(PDO::FETCH_ASSOC);
// I select all posts too
$stmt = $db->prepare("SELECT * FROM posts");
$stmt->execute();
$row_posts_all = $stmt->fetchAll(PDO::FETCH_ASSOC);
And then:
foreach ($row_posts_all as $array_index_number => $name_of_index) {
foreach ($row_categories as $array_index_number_categories => $name_of_index_category) {
print $name_of_index['post_title'] . " posted in: " . $name_of_index_category['category_name'] . "<br><br>";
}
}
I think this two foreaches part do things wrong. I can do one foreach to display all the posts but I do not know how to get their category names and put them next.
That's the reason we have JOINS,
SELECT * from posts p
LEFT JOIN categories c on c.id = p.category_id
And then you can simply need a single loop,
foreach ($row_posts_all as $array_index_number => $name_of_index) {
echo $name_of_index['post_title'] . " posted in: " . $name_of_index['category_name'] . "<br><br>";
}
select P.*, C.* from posts P
inner join categories C on C.category_id = P.category_id
You don't need 2 sql requests. So you don't need 2 loops
<?php
$q = mysql_query("SELECT sub_cat.*, links.*
FROM links
LEFT JOIN sub_cat
ON links.p_id = sub_cat.id
WHERE sub_cat.p_id = '$id'
ORDER BY name ASC") or die (mysql_error());
while ($r = mysql_fetch_assoc($q))
{
$links_name = $r['name'];
$link_h3 = $links_name != '' ? '<h3>' . $links_name . '</h3>' : '';
//print $link_h3;
print '<pre>';
print_r ($r);
}
?>
I have two tables with rows like:
sub_cat
id
name
p_id
links
id
links
p_id
In sub cat i have movie categories, like foreign language movies, national movies, uncategorised movies and so on. In links table i have concrete movie links and depending on sub category.
The only thing is that i do not want dublicate titles (sub_cat.name).
result is:
Without Category www.moviesite.com
Without Category www.moviesite2.com
Without Category www.moviesite3.com
Foreign Movies www.moviesite1.bla
Foreign Movies www.moviesite2.bla
I want to be
Without Category www.moviesite.com
www.moviesite2.com
www.moviesite3.com
Foreign Movies www.moviesite1.bla
www.moviesite2.bla
and do not have any idea how to do this :(
any help appreciated.
To do the job, you have 2 solutions:
The first solution is to process your data before showing it, in order to group all movies by category.
You can do for example:
$moviesByCategory = array();
while ($r = mysql_fetch_assoc($q))
{
// Create the new sub array for the new category if necessary
if (!isset($moviesByCategory[$r['name']]))
$moviesByCategory[$r['name']] = array();
// Add the movie in the category
$moviesByCategory[$r['name']][] = $r['links'];
}
And then, you can now iterate on this new array like
foreach($moviesByCategory as $category => $movies)
{
// Print the category name
echo '<h1>' . $category . '</h1>';
// Print all movies of the category
foreach($movies as $movie)
echo '<h3>' . $movie . '</h3>';
}
The second solution is to modify the SQL query to group directly all movies that have the same category. You just have to use a GROUP BY clause on sub_cat.id and then apply an agregate function on all other fields in the select.
For performance aspect, the best solution is the SQL solution, but doing it with PHP will give you more flexibility for the presentation.
Try something like:
$lastSubcatName = "";
while ($r = mysql_fetch_assoc($q))
{
$links_name = $r['name'];
if($lastSubcatName != $links_name)
{
echo "<h1>".$links_name."</h1>";
$lastSubcatName = $links_name;
}
echo '<h3>' . $r['links'] . '</h3>';
}
I am facing a bit of a problem and I am really not sure what I may be doing wrong. What I am trying to do is to create a proprietary forum that I can use for my clients and for my own projects. I agree that it's plain silly trying to reinvent the wheel instead of just ripping phpBB apart but this is also a good way for me to learn on my mistakes.
Problem
The problem is in the fact that the PHP script loop's the categories. For example we have 3 categories in SQL. Cookies, Cakes and Coffee now we have 2 forums for each say Like and Dislike in a proper forum they would look as such
Cookies
Like
Dislike
Cakes
Like
Dislike
And so on. However in mine it would look as such:
Cookies
Like
Cookies
Dislike
Code Ok here is the code for StackOverflow folks to rip appart and explain to me what I am doing wrong or what I may have missed or what I should do instead to make it function as it was intended to do.
<?php
//create_cat.php
include 'connect.php';
include 'header.php';
$sql = "SELECT
categories.cat_id,
categories.cat_name,
forums.forum_id,
forums.forum_cat,
forums.forum_name,
forums.forum_desc,
forums.forum_admin,
COUNT(forums.forum_id) AS forums
FROM
categories
LEFT JOIN
forums
ON
forums.forum_cat = categories.cat_id
GROUP BY
forums.forum_name, forums.forum_desc, forums.forum_id
ORDER BY
categories.cat_id ASC
";
$result = mysql_query($sql);
if(!$result)
{
echo 'The categories could not be displayed, please try again later.';
}
else
{
if(mysql_num_rows($result) == 0)
{
echo 'No categories defined yet.';
}
else
{
//prepare the table
while($row = mysql_fetch_assoc($result))
{
echo '<table border="1">
<tr>
<th>' . $row['cat_name'] . '</th><th></th>
</tr>';
echo '<tr>';
if ($_SESSION['user_level'] != 9 AND $row['forum_admin'] == 1) {
echo "<div style='padding:8px;background-color:#fae7af;'>Sorry but you this is for Admins only.</div><br>";
} else {
echo '<td class="leftpart">';
echo '<h3>' . $row['forum_name'] . '</h3>' . $row['forum_desc'];
echo '</td>';
echo '<td class="rightpart">';
//fetch last topic for each cat
$topicsql = "SELECT
topic_id,
topic_subject,
topic_date,
topic_cat
FROM
topics
WHERE
topic_cat = " . $row['forum_id'] . "
ORDER BY
topic_date
DESC
LIMIT
1";
$topicsresult = mysql_query($topicsql);
if(!$topicsresult)
{
echo 'Last topic could not be displayed.';
}
else
{
if(mysql_num_rows($topicsresult) == 0)
{
echo 'no topics';
}
else
{
while($topicrow = mysql_fetch_array($topicsresult))
echo '' . $topicrow['topic_subject'] . ' at ' . date('d-m-Y', strtotime($topicrow['topic_date']));
}
}
echo '</td>';
}
echo '</tr>';
echo '</br>';
}
}
}
include 'footer.php';
?>
SQL
**Category**
cat_id | int(8) | primary | auto incr
cat_name | var(255)
|2|Test 2
|3|Test 3
|1|Test 1
**Forum**
forum_id | int(8) | primary | auto_incr
forum_cat | int(8) <-- forum cat "category" is just ID of category it belongs to
forum_name | var(255)
forum_desc | var(255)
|1|1|Test|Just a simple forum test
|2|3|More Test | Just a 2nd test forum
|3|1|Bugs|Bugs and related go here
That's about it.
It looks to me like each category (cookies, cake, etc) has both forums (like, dislike). Am I reading that right?
If this is true, you should do an OUTER JOIN rather than a LEFT JOIN to produce the comprehensive list, like this:
...
FROM categories
JOIN forums
GROUP BY forums.forum_name, forums.forum_desc, forums.forum_id
ORDER BY categories.cat_id, forums.forum_id
Notice that the ON clause is gone. This means you'll get every forum row joined to every category row.
Notice also that you need to sort by both category and forum if you want the forums to be guaranteed to show up in the same order under each category.
If all forums do not appear for each category, but instead each category has a subset of your forums, the schema you have shown us isn't up to the job. You have a many-to-many relationship between the forums and categories table. To make this work you're going to need another table as follows:
forums_categories
cat_id int(8) not null
forum_id int(8) not null
PRIMARY KEY (cat_id, forum_id)
This table will need a row for each allowed combination of forum and category. Your from cause becomes:
...
FROM forums_categories fc
JOIN categories ON (fc.cat_id = categories.cat_id)
JOIN forums ON (fc.forum_id = forums.forum_id)
GROUP BY forums.forum_name, forums.forum_desc, forums.forum_id
ORDER BY categories.cat_id, forums.forum_id
Hope this helps.
I want to create a menu from category names in database, so far I have this:
$list = "SELECT category FROM posts";
$rlist = mysql_query($list) or die(mysql_error());
while($rows = mysql_fetch_assoc($rlist))
{
$catname = $rows['category'];
echo '<li>' . $catname . '</li>';
}
Which lists everything but I need to make each only list once so its a menu.
Maybe you want
SELECT DISTINCT category FROM posts;
And assuming you want them ordered
SELECT DISTINCT category FROM posts ORDER BY category ;
If you want your category to be only listed once, you chould change your query to
SELECT DISTINCT(category) FROM POSTS