I got stuck on something with PHP.,
I am trying to JOIN two tables
$statement = $database->prepare("SELECT categories.name as category_name ,pages.name as page_name FROM categories INNER JOIN pages ON categories.name = pages.category");
$statement->execute();
$fetch = $statement->fetchAll(PDO::FETCH_ASSOC);
$returnValues = '';
foreach($fetch as $item){
if(isset($returnValue[$item->category_name]){
array_push($returnValue[$item->category_name], $item->page_name);
}else{
$returnValue[$item->category_name][] = $item->page_name;
}
}
echo "<pre>";
print_r($returnValue);
Basically I want to get an array which got the category name and behind it all the pages that belongs to that category. now on this PHP code, I get plenty of array which everyone holds category name and one page.. and I can't sort it out , thanks.
Alias the category name so that you can tell it apart from the page name. This query will select the category name and all columns from table pages.
$statement = $database->prepare("SELECT categories.name AS category_name, pages.* FROM categories INNER JOIN pages ON categories.name = pages.category");
$statement->execute();
$fetch = $statement->fetchAll(PDO::FETCH_ASSOC);
Group each row by category name. Change $row['id'] to whatever you use as the primary ID for table pages.
$categoryPages = array();
foreach ( $fetch as $row ) {
$categoryPages[$row['category_name']][$row['id']] = $row;
}
print_r($categoryPages);
This is modifications to your original code, should basically do what you want, there might be some small syntax changes needed.
$statement = $database->prepare("SELECT categories.name as category_name ,pages.name as page_name FROM categories INNER JOIN pages ON categories.name = pages.category");
$statement->execute();
$fetch = $statement->fetchAll(PDO::FETCH_ASSOC);
$returnValues = '';
foreach($fetch as $item){
if(isset($returnValue[$item->category_name]){
array_push($returnValue[$item->category_name], $item->page_name);
}else{
$returnValue[$item->category_name][] = $item->page_name;
}
}
echo "<pre>";
print_r($returnValue);
Something like this might work for you... I know it is not perfect and there are something thing missing in the query prepare, but it should be enough to get you going.
The compiled array should be formatted the way you want.
$statement = $database->prepare("SELECT categories.name FROM categories");
$statement->execute();
$fetch = $statement->fetchAll(PDO::FETCH_ASSOC);
$compiled = '';
foreach($fetch as $category){
$statement = $database->prepare("SELECT page.name FROM pages WHERE pages.category = $category");
$statement->execute();
$pages = $statement->fetchAll(PDO::FETCH_ASSOC);
foreach($pages as $page)
array_push($compiled[$category], $page);
}
}
echo "<pre>";
print_r($compiled);
Related
Okay I try with the first query to get all names of the computers from the table psComputers. Now I need in the second query a variable from the first query to iterate over all entries which are assigned to the respective computer in the table psTest. I wonder if such a thing is possible at all?
Table psComputer contains ID, name
Table psTest contains ID, computername, category, value
index.php
$statement = $pdo->prepare("SELECT * FROM psComputers ");
$statement->execute();
$result = $statement->fetchAll();
if ($statement->rowCount() > 0) {
foreach ($statement->fetchAll() as $row) {
$id = $row['ID'];
$name = $row['name'];
$statement2 = $pdo->prepare("SELECT * FROM psTest WHERE computerName = $name");
$statement2->execute();
$result2 = $statement2->fetchAll();
if ($statement2->rowCount() > 0) {
foreach ($statement2->fetchAll() as $row2) {
$id2 = $row2['ID'];
$computerName = $row2['computerName'];
$category = $row2['category'];
$value = $row2['value'];
}
}
}
}
You need quotes around $name in the second query, since it's a string.
$statement2 = $pdo->prepare("SELECT * FROM psTest WHERE computerName = '$name'");
But since you're using a prepared query, you should use a parameter instead of substituting a variable.
You also shouldn't call $statement->fetchAll() twice. The first call will read all the rows, and the second won't have anything left to read (it doesn't reset the cursor).
$statement = $pdo->prepare("SELECT * FROM psComputers ");
$statement->execute();
$result = $statement->fetchAll();
if (count($result) > 0) {
$statement2 = $pdo->prepare("SELECT * FROM psTest WHERE computerName = :name");
$statement2->bindParam(':name', $name);
foreach ($result as $row) {
$id = $row['ID'];
$name = $row['name'];
$statement2->execute();
$result2 = $statement2->fetchAll();
if (count($result2) > 0) {
foreach ($result2 as $row2) {
$id2 = $row2['ID'];
$computerName = $row2['computerName'];
$category = $row2['category'];
$value = $row2['value'];
}
}
}
}
But even better is to just join the two queries:
$statement = $pdo->prepare("
SELECT c.id AS computerID, c.name AS computerName, t.id AS testID, t.category, t.value
FROM psComputers AS c
JOIN psTest AS t ON c.name = t.computerName
ORDER BY c.id");
A couple things to note,
When using strings in queries, they must be quoted.
You are already preparing the statement - bind the value instead, and the note above becomes irrelevant.
You can use a JOIN instead of running a query in a loop. This will also remove the variable in the name, making both notes above irrelevant! (You should take note of both, but they become irrelevant for the code in question).
Its rarely a good idea to run a query within a loop.
$statement = $pdo->prepare("SELECT pt.*
FROM psTest pt
JOIN psComputers pc ON pt.computerName=pc.name");
$statement->execute();
$result = $statement->fetchAll();
if (count($result)) {
foreach ($result as $row) {
$id2 = $row['ID'];
$computerName = $row['computerName'];
$category = $row['category'];
$value = $row['value'];
}
}
here is mytable structure?
table:category
id name
1 x
2 y
table:subproduct
id cat_id name myval
1 1 xyz test
2 1 abc test2
So basically i want to select all values from subproduct for each id of category table and show it in array in php?
here is my PHP code
$sqlnew = "SELECT c.cat_id,c.cat_title,s.sub_id,s.sub_title,s.store_cashback FROM category c JOIN subproduct s ON c.cat_id = s.pid";
$pdo = getDB();
$stmtnew = $pdo->query($sqlnew);
$resultnew = $stmtnew->fetchAll();
var_dump($resultnew);
I am using PHP PDO.
If you want to get all items with a particular category ID, you should do something like this:
$statement = $pdo->prepare("SELECT * FROM subproduct INNER JOIN category " .
"ON category.id = subproduct.cat_id WHERE category.id = :id");
$statement->bindValue(":id", $category_id, PDO::PARAM_INT);
$statement->execute();
$data = $statement->fetchAll();
You could use this to individually fetch each category ID and build an array like this:
$statement = $pdo->query("SELECT id FROM category;");
$ids = $statement->fetchAll(PDO::FETCH_COLUMN, 0);
$data = array();
foreach($ids as $id)
{
$statement = $pdo->prepare("SELECT * FROM subproduct INNER JOIN category " .
"ON category.id = subproduct.cat_id WHERE category.id = :id");
$statement->bindValue(":id", $id, PDO::PARAM_INT);
$statement->execute();
$data[$id] = $statement->fetchAll();
}
print_r($data);
I am not crazy about this because it looks inefficient and I don't like looping through queries. You could also request all the data at once and then rearrange it:
$statement = $pdo->query("SELECT * FROM subproduct");
$data = array();
while($subproduct = $statement->fetch(PDO::FETCH_ASSOC))
{
$id = $subproduct['cat_id'];
if (!isset($data[$id])
$data[$id] = array();
array_push($data[$id], $subproduct);
}
print_r($data);
I don't really like this either because using PHP to sort MYSQL data feels wrong since that is MYSQL's job. I could have requested MYSQL sort the data, but then the data would still need to be broken up into a multi-dimensional array, so I am not sure that helps.
I am not sure if the title expresses the problem accurately or not. Anyways, here is the explanation:
I have 2 tables, the first one holds users IDs, the other one holds their posts.
The fist query selects user IDs from the fist table, and it loop through the second table to find the users (IDs) posts.
The problem is that when the query finds eg. 5 results (user IDs 1, 6, 999.. etc) in the fist table, then it loops 5 times to search in the second table, it shows 5 results even if the real results is 2 post only created by user 1 and 6.
How can I avoid this repeatation?
Here is the code:
$stmt = $conn->prepare('select userid from table where para=?');
$stmt->bind_param('i', $para);
$stmt->execute();
$result = $stmt->get_result();
while( $row = $result->fetch_assoc()) {
$userid = $row["userid "];
$qname = "select postid,title from posts where uid='$userid'";
$result2 = $conn->query($qname);
$row2 = $result2->fetch_array(MYSQLI_ASSOC);
if ($row2 > 0) {
$postid= $row2['postid'];
$title= $row2['title'];
}
echo $postid." ".$title."<br>";
}
Try
$qname = "select postid,title from posts as P left join table as T on T.userid=P.uid where where para=?";
Or
You can store the results in a common array during the loop.
like
$tempResult = array();
while( $row = $result->fetch_assoc()) {
$userid = $row["userid "];
$qname = "select postid,title from posts where uid='$userid'";
$result2 = $conn->query($qname);
$row2 = $result2->fetch_array(MYSQLI_ASSOC);
if ($row2 > 0) {
$tempResult[$userid][] = $row2['postid'];
$tempResult[$userid][] = $row2['title'];
}
}
you can try this query using a JOIN MYSQL.
SELECT u.userid,p.postid,p.title FROM TABLE `user` u
JOIN posts p ON
p.uid = u.userid
WHERE para=?
You can avoid it by only running one query that joins the two tables together. Something like this:
<?php
$stmt = $conn->prepare('select posts.* from table t inner join posts p on t.userid = p.uid where t.para = ? order by uid');
$stmt->bind_param('i', $para);
$stmt->execute();
$result = $stmt->get_result();
while( $row = $result->fetch_assoc()) {
// $row now has userid, and all post details
}
?>
I was working on a post system..
So, I have to show posts by friends of the user and the groups in which user has participated..
Here is my code to show posts..
<?php
$sql = "SELECT * FROM posts WHERE uploader_id=:friend_id ORDER BY id DESC";
$query = $db->prepare($sql);
$query->execute(array(
":friend_id" => $friend_id
));
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$name = $row['name'];
echo "POST BY $name";
}
$sql = "SELECT * FROM group_posts WHERE id=:member_group ORDER BY id DESC";
$query = $db->prepare($sql);
$query->execute(array(
":member_group" => $group_id
));
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$name = $row['name'];
echo "POST BY $name";
}
?>
Now, I want all these posts to be shuffled in a way that all the posts of the post table and group_posts table are shown in the descending order.
UPDATE
I edited my code to this..
I figured out that first I'll have to code this before coding my post system..
<?php
$sql = "SELECT * FROM friends WHERE user_one=:me OR user_two=:me2 UNION SELECT * FROM group_members WHERE member_id=:me3";
$query = $db->prepare($sql);
$query->execute(array(
":me" => $my_id,
":me2" => $my_id,
":me3" => $my_id
));
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$user_one = $row['user_one'];
$user_two = $row['user_two'];
$group_id = $row['group_id'];
if ($user_one == $my_id) {
$friend_id = $user_two;
} else {
$friend_id = $user_one;
}
echo $friend_id . "<BR>" . $group_id;
}
?>
Now, here's the problem..
This is successfully printing the $friend_id but, it shows an undefined index 'group_id' while printing $group_id.
I have checked all the fields are correct.
Try using just one query with UNION
SELECT *
FROM (
SELECT name, id FROM posts WHERE uploader_id=:friend_id
UNION
SELECT name, id FROM group_posts WHERE id=:member_group
) p
ORDER BY p.id DESC
Note, your inner queries must return the same number of columns in the same order (and I think with the same name/alias, too).
I'm trying to select one query by using the user_id to get the categories specific to the user and then from there use the results from the first query to select data from a second table in a second query. The data from the second query I would like to display in a drop down menu. Is there any easy way to do this? I'm new to using mysqli so please bear with me.
I have the following function but it's not displaying anything in the dropdown menu, it is showing the drop down menu though.
function get_classes($mysqli) {
if(isset($_SESSION['user_id'], $_SESSION['username'], $_SESSION['login_string'])) {
$user_id = $_SESSION['user_id'];
if ($stmt = $mysqli->prepare("SELECT category_id
FROM questions WHERE user_id = ?")) {
$stmt->bind_param('i', $user_id);
$stmt->execute();
$stmt->store_result();
if($stmt->num_rows>0) {
$stmt->bind_result($category_id);
$stmt->fetch();
if($result = $mysqli->prepare("SELECT category_id, category_name
FROM category WHERE category_id = ?")) {
$result->bind_param('s', $category_id);
$result->execute();
$result->store_result();
}
}
echo "<select id='classes' name='classes'>";
while ($row = $result->fetch_assoc()) {
unset($user_id, $category_name);
$category_id = $row['category_id'];
$category_name = $row['category_name'];
echo '<option value="'.$category_id.'">'.$category_name.'</option>';
}
echo "</select>";
}
}
}
I'm calling the function from another page with the following code:
<?php
get_classes($mysqli);
?>
You can make all via one sql query:
SELECT c.category_id, c.category_name
FROM questions q
INNER JOIN category c ON c.category_id = q.category_id
WHERE q.user_id = ?
Alternatively, you could join them instead, then the normal fetching. Example:
function get_classes($mysqli) {
if(!isset($_SESSION['user_id'], $_SESSION['username'], $_SESSION['login_string'])) {
return false;
}
$user_id = $_SESSION['user_id'];
$sql = '
SELECT
category.category_id,
category.category_name
FROM category
JOIN questions
ON questions.category_id = category.category_id
WHERE questions.user_id = ?
';
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $user_id);
$stmt->execute();
$result = $stmt->bind_result($category_id, $category_name);
// printing
echo '<select name="classes" name="classes">';
while($row = $stmt->fetch()) {
echo '<option value="'.$category_id.'">'.$category_name.'</option>';
}
echo '</select>';
}