1

Ive been trying to figure this out but im not sure how to do this. I have a select statement that querys the database and returns an array. That array is then used to query the database again. I am not sure how to save the second array.

        $stmt = $dbh->query("SELECT user_id FROM users WHERE username = '" . $user_name . "'");
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        $user_id = $row['user_id'];

        $stmt = $dbh->query("SELECT friend_id FROM friends WHERE user_id ='" . $user_id . "'");
        $ret_array = $stmt->fetchAll(PDO::FETCH_ASSOC);

        for($i = 0; $i<count($ret_array); $i++) {
            $stmt = $dbh->query("SELECT profile_path, username FROM users WHERE user_id=" .$ret_array[$i]['friend_id']);
        }
        $show_all_friends = $stmt->fetchAll(PDO::FETCH_ASSOC);

        return $show_all_friends;

This is my code and i want the values that are obtained in the forloop to be saved into $show_all_friends. How can i do this?

3
  • 2
    How can i do this? - by not sending X single SELECTs but using a JOIN - see en.wikipedia.org/wiki/Join_%28SQL%29 for starters. It's THE singlemost important concept in relational database systems - in fact it's the "relational" in "relational database" and it's not the first word for nothing ;-) There are other types of databases but as long as you stick with RDBSs learn the concept of JOIN. Commented Feb 16, 2015 at 9:58
  • I would use join but im selecting from the same table twice with a different condition. Will it still work if i use join? Commented Feb 16, 2015 at 10:09
  • Yes, it will ....unless you have temporary/memory tables, in which case (better check the manual if it still applies) MySQL will tell you that it can't do that with such table. Commented Feb 16, 2015 at 10:11

3 Answers 3

1

You don't have to make a loop, just 2 queries with binding method for more security and performance.

$sth = $dbh->prepare("SELECT user_id FROM users WHERE username = ?");
$sth->bindParam(1, $user_name, PDO::PARAM_STR);
$sth->execute();
$row = $sth->fetch(PDO::FETCH_ASSOC);
$user_id = $row['user_id'];

$sth = $dbh->prepare('SELECT u.profile_path, u.username 
FROM users u JOIN friends f on f.friend_id = u.user_id
WHERE f.user_id = ?');
$sth->bindParam(1, $user_id, PDO::PARAM_INT);
$sth->execute();

return $sth->fetchAll(PDO::FETCH_ASSOC);
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much this worked :) much appreciated, I just used ":user_id" instead of useing a place holder.
1

Use a single query using two JOINS.
You can "use" the same table twice by giving it unique aliases within the query so any reference to that table is unambigious.
As mentioned in the comments to your question, this won't work for temporary tables with MySQL. Therefore the following example does not use CREATE TEMPORARY TABLE.... in the setup() function. I usually try to avoid that. So, keep in mind that this example might overwrite exsting tables (though I hope the table name is quite unique) and it persists data on your database server.

<?php
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly');  
//echo 'client version: ', $pdo->getAttribute(PDO::ATTR_CLIENT_VERSION), "\n";
//echo 'server version: ', $pdo->getAttribute(PDO::ATTR_SERVER_VERSION), "\n";
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
setup($pdo);


$stmt = $pdo->prepare('
    SELECT
        u2.user_id
    FROM
        soNOTTEMPUsers as u1
    JOIN
        soNOTTEMPFriends as f
    ON
        u1.user_id=f.user_id
    JOIN
        soNOTTEMPUsers as u2
    ON
        f.friend_id=u2.user_id
    WHERE
        u1.username=:username
');

$stmt->bindParam('username', $username);
foreach( array('userA', 'userB', 'userC', 'userD') as $username ) {
    echo 'querying friends of ', $username, "\r\n";
    $stmt->execute();
    foreach( $stmt as $row ) {
        echo '  ', join(', ', $row), "\r\n";    
    }
}

function setup($pdo) {
    $queries = array(
        '
            CREATE TABLE IF NOT EXISTS soNOTTEMPUsers (
                user_id INT,
                username varchar(32),
                primary key(user_id)
            )
        ',
        '
            CREATE TABLE IF NOT EXISTS soNOTTEMPFriends (
                user_id INT,
                friend_id INT,
                primary key(user_id, friend_id)
            )
        ',
        "REPLACE soNOTTEMPUsers (user_id, username) VALUES
            (1, 'userA'), (2, 'userB'), (3, 'userC'), (4, 'userD')
        ",
        "REPLACE INTO soNOTTEMPFriends (user_id, friend_id) VALUES
            (1,2),(1,3),(1,4),
            (2,1),(2,3),(2,4),
            (3,1),(3,4),
            (4,1)
        ",
    );
    foreach( $queries as $q ) {
        $pdo->exec($q);
    }

}

prints

querying friends of userA
  2, 2
  3, 3
  4, 4
querying friends of userB
  1, 1
  3, 3
  4, 4
querying friends of userC
  1, 1
  4, 4
querying friends of userD
  1, 1

as expected (though not tested for consistency like a friendof b <=> b friendof a)

Comments

0

PLease change your code with following code

$stmt = $dbh->query("SELECT user_id FROM users WHERE username = '" . $user_name . "'");
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    $user_id = $row['user_id'];

    $stmt = $dbh->query("SELECT friend_id FROM friends WHERE user_id ='" . $user_id . "'");
    $ret_array = $stmt->fetchAll(PDO::FETCH_ASSOC);

    for($i = 0; $i<count($ret_array); $i++) {
        $stmt = $dbh->query("SELECT profile_path, username FROM users WHERE user_id=" .$ret_array[$i]['friend_id']);
        $show_all_friends[] = $stmt->fetchAll(PDO::FETCH_ASSOC);
    }


    return $show_all_friends;

Hope this helps

2 Comments

I tried this but it still doesnt return all the values. only the last one
fetch only single record from users table by using only "fetch" keyword $show_all_friends[] = $stmt->fetch(PDO::FETCH_ASSOC);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.