I've got some PHP that builds and executes a query using PDO. The query is getting usernames and user images from a users
table, and ID parameters are added to it from an array in a PHP for loop. Thus, the query looks something like this once it's built:
SELECT username, image FROM users WHERE id=4 OR id=2 OR id=16 OR id=8 OR id=9;
The PHP expects as many rows to be returned from the query as there were ID values plugged into it. This works just fine when all the IDs are unique, but when there are identical IDs in the query, MySQL (efficiently) returns only one row for each unique ID, as below.
SELECT username, image FROM users WHERE id=4 OR id=2 OR id=2 OR id=4 OR id=2;
This query would only return 2 rows, one for the user with ID 4 and one for user ID 2. Like I said, the application expects as many rows returned as ID parameters submitted, so this is a problem. Is there a different way to phrase my SQL query to force it to return identical rows?
Just make your application refine input data by taking out duplicates. Thus, only two ids will be sent and two lines will satisfy the expectation.
You can filter the array, taking only the uniques values, and then use IN in your query:
<?php
$array = array(2, 3, 4, 5, 5, 5, 4, 3, 2, 1);
$array = array_unique( $array );
// when only numeric values
$values = implode(",", $array );
// when strings
//$values = "'" . implode("','", $array ) . "'";
$query = 'SELECT username, image FROM users WHERE id IN( ' . $values . ')';
?>
Get the frequency of each value in array. After, make a loop and write one query with limit for each id, then, union all query's.
<?php
$array = array(2, 4, 2, 2, 4);
$values = array_count_values($array);
$query = array();
foreach ($values as $id => $frequency)
{
$query[] = "SELECT username, image FROM users WHERE id = {$id} LIMIT {$frequency}";
}
$query = implode(" UNION ", $query);