Reputation: 745
I'm trying to optimize the speed of data processing and would like to have any suggestions for a scalable solution to the following:
I have a PHP array looking like:
$arr = array(
2543 => 1,
2123 => 2,
2431 => 1,
3223 => 3,
...
);
Here the keys represent unique item ids and the value, orders of these ids in a system. Using this (very big) array I would like to extract the items assign them their priority and sort in the most efficient manner.
My current solution is rather straight forward (using PDO and primarily based on PHP):
$item_ids = array_keys($arr);
$item_ids_csv = implode(",", $item_ids);
$sql = "SELECT `id`,`name`
FROM `item_data`
WHERE `id` IN ($item_ids_csv);";
#execute is a custom function returning a PDO execution
$items = $this->execute($sql)->fetchAll(PDO::FETCH_ASSOC);
foreach($items as &$item){
$item['order'] = $arr[$item['id']];
}
usort($items, function($a, $b) {
return $a['order'] - $b['order'];
});
print_r($items);
Which works just fine, but I'm however wondering if the above PHP operation is possible entirely in SQL? Maybe I could INNER JOIN
the orders ON
each id and ORDER BY
these?
I'm figuring that it wound save me some processing time to shift this logic to the database, correct me if I'm wrong.
Upvotes: 0
Views: 149
Reputation: 1270713
You can do the ordering in the database, with a single query by splitting the values into three groups:
select id, name
from item_data
order by (id in ($items_ids_csv_1)) desc,
(id in ($items_ids_csv_2)) desc,
(id in ($items_ids_csv_3)) desc;
This works because the expression id in (...)
returns "1" when the id
is in the list and "0" otherwise.
Upvotes: 1
Reputation: 3405
As I suggested in a comment, if there are only 3 sequence values, split it into 3 parts:
# make 3 different $item_ids_csv
$item_ids_csv_1 = ...
$item_ids_csv_2 = ...
$item_ids_csv_3 = ...
...
$sql = "SELECT `id`,`name`,1 AS seq
FROM `item_data`
WHERE `id` IN ($item_ids_csv_1)
UNION
SELECT `id`,`name`,2 AS seq
FROM `item_data`
WHERE `id` IN ($item_ids_csv_2)
UNION
SELECT `id`,`name`,3 AS seq
FROM `item_data`
WHERE `id` IN ($item_ids_csv_3)
ORDER BY seq, id;";
Upvotes: 0