Autor Zpráva
anonymníí
Profil *
Ahoj,

nadpis je trochu krkolomný, pojďme se podívat rovnou na příklad.

$item_ids = [460, 443, 134, 444, 445];
$query = "SELECT ... WHERE product IN " . implode(',', $item_ids) . " ... WHERE ... GROUP BY ... ORDER BY ??? LIMIT 10";
$result = ...;

while ($row = fetch($result)) {
    $data[] = $row;
}

Jelikož IN negarantuje pořadí a nyní se mi stalo, že mám výsledky řazeny jinak než bych potřeboval, chci se zeptat, jak to co nejlépe řešit, ideálně na úrovni SQL dotazu, nebo v PHP? Myslím, že lepší bude rovnou SQL, než složit nějaké pole v PHP a pak ho nějak přeskládat (lepší řešení než projití foreachem mě nenapadlo).

Záznamů je a bude celkem málo, řekněme 10-20 max, více nikdy ne.

Otázka je, jak mám říct SQL dotazu, aby mi vrácené záznamy setřídil v pořadí, v jakém jsem mu je předal? Řazení není ničím specifické, nejde řadit dle nějakého sloupce v daném dotazu, skutečně bych potřeboval vrátit záznamy tak, jak mu přijdou v řadě v tom poli (to může přijít dejme tomu zvenčí).

Zkoušel jsem různé šachy s použitím klíčů v původním poli, ale nikam jsem se nedostal. Jasně, prasárna mě napadla, v ORDER BY dát podmínku na ID každého záznamu, ale nevím, jestli to tu mám psát takhle viditelně... nechám to tu, nerad :-) Vzniko by něco jako

ORDER BY 
item = 460,
item = 443,
...
item = 445

ale to samozřejmě není zcela ono.

Děkuji za radu.
scheras
Profil *
Jelikož opravdu pořadí není garantované a, jak zmiňujete, nijak jinak to z databáze také nelze odvodit, bude se to muset řešit pravděpodobně na úrovni PHP. Napadají mě dvě řešení:

1/ Pro každé ID vlastní dotaz. To bude bohužel vždy nutně pomalejší, než když se provede pouze jeden dotaz, ale psal jste, že jich nikdy nebude moc. Tedy něco jako:
$item_ids = [ 460, 443,134,444,445 ];

foreach ( $item_ids as $item_id ) {
   $query = "SELECT ... WHERE product = " . $item_id . " ...";
   $result = ...;
   $data[] = fetch($result);
}

2/ Použít dotaz tak, jak ho máte napsaný a následně seřadit pole s výsledky:
$item_ids = [460, 443, 134, 444, 445];
$query = "SELECT ... WHERE product IN " . implode(',', $item_ids) . " ... WHERE ... GROUP BY ... ORDER BY ??? LIMIT 10";
$result = ...;
 
while ($row = fetch($result)) {
    $key = array_search($row[ 'product' ], $item_ids);
    $data[ $key ] = $row;
}

Jinak doufám, že váš kód je bez escapování jen kvůli zjednodušení ukázky. Jinak si totiž zaděláváte na veliký problém.
anonymnii
Profil *
scheras:
Sólo dotaz pro kazde ID určitě ne, to neni spravna cesta, a ač si v SQL nejsem jisty v kramflecich, tak takhle určitě ne. Ale díky za reakci, ještě počkám na další :-)
scheras
Profil
anonymnii:
Jak je libo. Také jsem u těch jednotlivých dotazů na problémy s rychlostí upozorňoval.
Jen ze zvědavosti, co se vám nezdá na tom druhém řešení?
Taps
Profil
A co pouzit order by field, viz napr stackoverflow.com/questions/5090591/mysql-select-where-id-in-correct-order
anonymnii
Profil *
scheras:
Rychlost, bude to pomalé.

Taps:
To vypada dobre, díky za odkaz. Ještě si o tom něco přečtu jinde, ale mohlo by to byt, co hledám.
midlan
Profil
Ještě přidám jednu možnost, scherasova první metoda by šla modifikovat na jeden dotaz pomocí UNION SELECT. Dotazy se vykonají samozřejmě všechny, jen do databáze to přijde najednou, takže by se to myslím zrychlilo. Řešení od Taps, na které odkázal, ale vypadá lépe :)

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: