I am trying to compare items in two different DB tables - php

I'm having trouble getting this to work correctly on my classifieds website, but basically what I am doing is taking all from an Item table LIMIT 40 and displaying it on page. Now for the hard part, I am taking all from a category table, which contains the names of the categories (each category name has a relative id). I need to print out the name of the category WHEN its id is equal to the id of the item. Hopefully the code will help clarify:
$sql = mysql_query("SELECT * FROM table_item ORDER BY creationtime DESC LIMIT 40");
$sql2 = mysql_query("SELECT * FROM table_category");
$ad_count = mysql_num_rows($sql);
$row2 = mysql_fetch_array($sql2);
if($ad_count > 0){
while($row = mysql_fetch_array($sql)){
$item_categoryId = $row["cid"];
$categoryId = $row2["id"];
$categoryName = $row2["name"];
while($item_categoryId == $categoryId){
$catName = $categoryName;
}
echo $catName;
}
}
Now, there is a little more to the code then what I put up, I tried to keep this short and sweet. Instead of echoing the category name, its actually being put into an HTML table row and there is also a lot more information being put in as well. Everything works fine when I don't do anything with the category name, but when I try to build something to access and compare it, then everything goes to shit.
Also, I should mention that this nested while loop seemed to be the best way to go about this (I have tried many ways) and the error I am getting for this is that "there is an unexpected '}'".

Use joins instead of nested loops:
SELECT
*
FROM
table_item,
INNER JOIN
table_category
ON
table_item.cid=table_category.id
ORDER BY
creationtime DESC
LIMIT 40
If not every item has a corresponding category, use LEFT JOIN instead of INNER JOIN.

Related

PHP Output data from 3 different tables

I'm trying to display a HTML table with information from 3 different tables in my mysql DB. However I am unsure on how to display the information from the third table.
Currently what I am using is:
$SQL = "SELECT members.*, exp.*, lvl.*
FROM members
INNER JOIN exp ON members.id = exp.member_id
INNER JOIN lvl ON members.id = lvl.member_id
ORDER BY lvl.level DESC,
lvl.total DESC, xp.total DESC";
$result = mysql_query($SQL) or die(mysql_error());
$count = 1;
while ($row = mysql_fetch_assoc($result)) {
$level = $row['level'];
$exp = $row['exp.overall'];
}
the $level is from the second table which grabs correctly, and the $exp is what I want to grab from the third table which is "exp" but it doesn't return anything
How can I change this because at the moment it just seems to be focusing on the data from the "lvl" table when using $row[]
Edit: Both the lvl and exp tables have a row in called 'overall' which is why using $row['overall'] doesn't return what I want as it returns the data from lvl table rather than exp.
First off I believe you have a typo in your last order column: should be exp.total DESC.
Secondly, unless you specify the columns to be named with dot notation explicitly they will retain their column names so try changing the last line to:
$exp = $row['overall'];.
Also consider using mysqli or PDO.

How can I select all id's from a sql table in descending order and then echo them (in php)?

I have several id's in a table called "leaderboards" that belong to different users. They're named as:"id_user" and they're not in order. What I want to do is printing divs in a leaderbord which should contain some info that I get from those id_user's.
The only problem I have about it is that after a research on stackoverflow and other websites, I still couldn't find how to select those id_user's in descending order AND be able to take one by one to get the info from that user and then continue with the next id_user, and so on.
I don't know how to select the specific row of each id_user in descending order to do the other codes that I already know how to do.
I hope it's not a duplicate of any other previosly asked question on this website (I really did a research and I couldn't find any specific answer to this question, for the sql part and the php part all together).
Thank you so so much beforehand.
An INNER JOIN between your tables will achieve what you intend.
SELECT *
FROM users
JOIN leaderboards WHERE users.id = leaderboards.id_user
ORDER BY users.id DESC
In each returned row, you will get the columns from both your users and leaderboards tables, so loop over the result and echo the information from the user you need.
$query = 'SELECT...';
$res = mysqli_query($query);
while ($row = mysqli_fetch_assoc($res)) {
echo '<div>'.$row['id'].' - '.$row['username'].' - '.$row['image'].'</div>';
}
You could do with a good read up on both PHP and MySql but I'll give you a clue.
EDIT
$query = "SELECT * FROM `the_name_of_your_table` ORDER BY `user_id` DESC;";
if ($result = mysqli_query($link, $query)) {
/* fetch associative array */
while ($row = mysqli_fetch_assoc($result)) {
print $row["user_id"] . " - " . $row["username"] . "<BR>";
}
/* free result set */
mysqli_free_result($result);
}

Which is the query i should do so that i could fetch the previous from last row?

I want to read the last 3 rows of my table seperate and then place them in 3 different div's of a slider. The problem is that i cant use 'where id=xxx' because i insert rows dynamically every time that i make a post item.
if i use query('select * from news order by id desc limit 3') and then a loop while ($result->fetch_assoc()) then i have the last 3 rows.
My problem is that i want to place every row in a different div so that i will have 3 divs.
I suppose i must do 3 different queries for that but i dont know how.
I have this one right now.
$result = $myDb->query('select * from news order by id desc');
while ($nI = $result->fetch_assoc()) {
$title = $nI['title'];
$date = $nI['date'];
$author = $nI['author'];
$mainobjective = $nI['mainobjective'];
$contents = $nI['contents'];
$keywords = $nI['keywords'];
and then i have my html where with the use of echo i place every variable in the div i want.
It sounds like the problem you are describing is more with your PHP code, that you haven't posted, than your MySQL. Don't read them separately. Use a single query to get all 3 and then iterate through them separately with PHP.
You can use the query you already had:
$result = $myDb->query('SELECT * FROM news ORDER BY id DESC LIMIT 0,3');
Make sure you are placing the results in separate containers in PHP:
foreach($result as $row)
{
echo "<div>".$row."</div>";
}

Left join MySql/PHP

Whilst populating a table based on ids and labels from different tables, it appeared apparent there must potentially be a better way of achieving the same result with less code and a more direct approach using LEFT JOIN but i am puzzled after trying to work out if its actually capable of achieving the desired result.
Am i correct in thinking a LEFT JOIN is usable in this instance?
Referencing two tables against one another where one lists id's related to another table and that other table has the titles allocated for each reference?
I know full well that if theres independent information for each row LEFT JOIN is suitable, but where theres in this case only several ids to reference for many rows, i just am not clicking with how i could get it to work...
The current way i am achieving my desired result in PHP/MySQL
$itemid = $row['item_id'];
$secid = mysql_query(" SELECT * FROM item_groups WHERE item_id='$itemid' ");
while ($secidrow = mysql_fetch_assoc($secid)) {
//echo $secidrow["section_id"]; //testing
$id = $secidrow["section_id"];
$secnameget = mysql_query(" SELECT * FROM items_section_list WHERE item_sec_id='$id' ");
while ($secname = mysql_fetch_assoc($secnameget)) {
echo $secname["section_name"];
}
}
Example of the data
Item groups
:drink
:food
:shelf
Item List
itemId, groupId
Group List
groupId, groupTitle
The idea so outputting data to a table instead of outputting "Item & Id Number, in place of the ID Number the title actually appears.
I have achieved the desired result but i am always interested in seeking better ways to achieve the desired result.
If I've deciphered your code properly, you should be able to use the following query to get both values at the same time.
$itemid = $row['item_id'];
$secid = mysql_query("
SELECT *
FROM item_groups
LEFT JOIN items_section_list
ON items_section_list.item_sec_id = item_groups.section_id
WHERE item_id='$itemid'
");
while ($secidrow = mysql_fetch_assoc($secid)) {
//$id = $secidrow["section_id"];
echo $secidrow["section_name"];
}

A Better Way to Implement Mult. Categories For 1 Post in PHP?

Assume, I have the Following Tables in my Database.
POSTS:
id, title, content
CATEGORIES:
id, name
RELATION:
post_id, cat_id
I have been succesfully able to insert the values into these tables, while publishing the post.
I am also, able to display the categories beneath each and every post on my Homepage. But, I Fear the method I am using is very resource intensive.
Here is What I Do in MySQL/PHP.
(You can choose to skip the code, and read its description for better understanding)
//Get all the posts
$database = $connection->prepare("Select * FROM POSTS");
$database->execute(array());
$result = $database->fetchAll(PDO::FETCH_ASSOC);
foreach ($result as $r) {
$articleid = $r['id'];
//Display Post title and other things here
//Get the Category Ids
$database = $connection->prepare("Select * FROM RELATION WHERE post_id = ".$article);
$database->execute(array());
$ret_cat= $database->fetchAll(PDO::FETCH_ASSOC);
//Get names of category, and dislay them
foreach($ret_cat as $rc)
{
$catid = $rc['cat_id'];
$database = $connection->prepare("Select * FROM CATEGORIES WHERE cat_id= ".$catid);
$database->execute(array());
$ret_cat_name= $database->fetch(PDO::FETCH_ASSOC);
echo "<a href='index.php?category=".$rc['cat_id']."'>".$ret_cat_name['name']."</a> ";
}
}//End First ForEach
Select All the the Desired Posts from the POSTS table.
Use a Foreach loop to display each post.
Within the foreach loop, I use another SELECT statement to get the categories from RELATION table by matching the POSTS.id.
Then, I Use another foreach loop to display all the categories.
But, since I have only the category id in the RELATION table and I need to display the name of the Category instead.
So, I use another SELECT statement to get the name of the Category from the CATEGORIES table, by using RELATION.cat_id.
The Code Works Fine, and I get what I want. But, I feel there are a lot of mysql requests being generated. Hence, load would be increased on server.
So, I need to know what I am doing is right or not. Or, if there is a simpler way to do all this?
Why not use JOIN to decrease the number of database round-trips?
For example, first select the desired posts...
SELECT * FROM POSTS WHERE <some filter criteria for posts>
...and then for each returned row...
SELECT CATEGORIES.*
FROM RELATION JOIN CATEGORIES
ON RELATION.cat_id = CATEGORIES.id
WHERE
post_id = <value from the first query>
Or even do everything in a single round-trip...
SELECT POSTS.*, cat_id, name
FROM POSTS
JOIN RELATION
ON POSTS.id = RELATION.post_id
JOIN CATEGORIES
ON RELATION.cat_id = CATEGORIES.id
WHERE
<some filter criteria for posts>
...in which case the client code would need to "merge" the resulting rows that have the same POSTS.id.
BTW, you should almost never do something like...
Select * FROM POSTS
...without a WHERE clause. This simply won't scale as the database grows.

Categories