Search code examples
phpmysqlpdosql-limitsql-in

PHP PDO with IN clause and LIMIT


I'm trying to execute statement with IN clause using PDO and with LIMIT.

Following this tutorial https://phpdelusions.net/pdo#in I've managed to build code that is working, but doesn't retrieve data as it should

        $inStmt = DB::prepare("SELECT following_user_id FROM following WHERE user_id=?");
        $inStmt->execute([$userId]);
        $arr = ($inStmt->fetchAll(PDO::FETCH_NUM));
        $array = array();
        foreach ($arr as $element ) {
            $array = array_merge($array, $element);
        }
        $in  = str_repeat('?,', count($array)) . '?';

        $params = array_merge($array,[$userId]);
        $sql = "SELECT * FROM user_tweets WHERE user_id IN ($in) ORDER BY tweet_date DESC LIMIT 20 OFFSET ?";
        $stmt = DB::prepare($sql);  
        for ($x = 0; $x <= count($params) - 1; $x++) {
            $param = $params[$x];
            echo " ID:" .($x+1) . " PARAM:". $param;
            $stmt->bindParam(($x+1),$param);
        } 
        $param = (int)$startFrom;
        echo " ID:" .(count($params)+1) . " PARAM:". $param;
        $stmt->bindParam((count($params)+1),$param,PDO::PARAM_INT);
        $stmt->execute();
        return $stmt->fetchAll(PDO::FETCH_ASSOC);

For example first statement returns array of [43,42]. Then I merge it with 53 so I got [43,42,53]

These are the echoes from this example

ID:1 PARAM:42 ID:2 PARAM:41 ID:3 PARAM:53 ID:4 PARAM:0

Query also creates as it should:

SELECT * FROM user_tweets WHERE user_id IN (?,?,?) ORDER BY tweet_date DESC LIMIT 20 OFFSET ?

What is wrong with my code? I'm confused because everything should be fine (when I call my database with already set variables like below it does return couple rows so it should be working also with PDO but returns nothing)

SELECT * FROM user_tweets WHERE user_id IN (42,41,53) ORDER BY tweet_date DESC LIMIT 20 OFFSET 0

Solution

  • This seems a simpler (and infinitely faster) way of doing much the same thing:

    SELECT t.*
      FROM following f
      JOIN user_tweets t
        ON t.user_id = f.following_user_id
     WHERE f.user_id=?
     ORDER 
        BY t.tweet_date DESC