Toon posts:

[PHP+MySQL] handmatige sortering?

Pagina: 1
Acties:

Verwijderd

Topicstarter
Joe,

Ik heb een functie die een array met ids accepteert een een array met PHP-objecten (op basis van mysql-rows) retourneert. Echter, ik wil dat de volgorde van retourneren van de objecten op basis van de volgorde van de opgevraagde ids hebben.
Heeft iemand enig idee hoe dit kan? Voorbeeldje van hoe zo'n query er uit zou moeten zien:
code:
1
2
3
SELECT * FROM objecten 
WHERE id IN ($OBJIDS)
ORDER AS (id1, id2, id3, ..., id200)


maar "ORDER AS" bestaat natuurlijk niet. Is hier een MySQL-oplossing voor (met de nodige optimalisaties), in plaats van een PHP implementatie?

  • Cloud
  • Registratie: November 2001
  • Laatst online: 18-02 09:57

Cloud

FP ProMod

Ex-moderatie mobster

Bij mijn weten is die er niet. Ik had laatst een soortgelijke situatie en die heb ik daarmee helaas niet op kunnen lossen. :) En op de MySQL site vind ik ook geen enkele hint dat zoiets mogelijk is.

Never attribute to malice that which can be adequately explained by stupidity. - Robert J. Hanlon
60% of the time, it works all the time. - Brian Fantana


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 09-12-2025
Je selecteert dus een stel records en die wil je sorteren op ID? Zo dus:
SQL:
1
SELECT * FROM objecten ORDER BY id


Als je al een serie ID's in een array hebt dan kun je dit doen:
PHP:
1
2
3
$IDs = array(1, 5, 3, 2, 4, 3);
array_sort($IDs);
print_r($IDs);


Of anders zo:
PHP:
1
2
3
4
5
6
7
8
9
10
11
$objecten = array(
  array('id' => 2, 'naam' => 'abc'),
  array('id' => 3, 'naam' => 'def'),
  array('id' => 1, 'naam' => 'xyz')
);
$IDmap = array();
foreach ( $objecten as $key => $object )
{
  $IDmap[$key] = $object['id'];
}
array_multisort($IDmap, SORT_ASC, $objecten);


Dat is wel zo'n beetje wat je hoeft te weten.


Edit: Volgens mij begreep ik je probleem niet helemaal :P

[ Voor 18% gewijzigd door Michali op 26-06-2006 16:19 ]

Noushka's Magnificent Dream | Unity


  • frickY
  • Registratie: Juli 2001
  • Laatst online: 17-02 09:21
Even ongetest en uit het hoofd, denk ik dat het met zoiets zou moeten lukken;
Waarbij je dus getRows() aanroep met een array met de ID's welke je wilt hebben.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
function getRows($arrIDs) {
    $result = mysql_query("
        SELECT *
        FROM objecten
        WHERE ID IN (" . implode(", ", $arrIDs) . ")");     
    $getRows = array();
    while($row = mysql_fetch_object($result)) {
        $getRows[$row['ID']] = $row
    }
    $ordered = array_flip($arrIDs);
    $ordered = array_merge($ordered, $getRows);
    return $ordered
}


Als je het in de query zelf wilt oplossen kun je misschien dit proberen;
SQL:
1
ORDER BY ID = 12 DESC, ID = 6 DESC, ID = 9 DESC, ID = 21 DESC

(ID = 12) geeft 1 voor het record met het ID 12, en voor alle overige 0. Enz. Ik weet alleen niet of de ORDER BY op een dergelijke manier geevalueerd wordt.
// Edit
Getest en werkt in MySQL 5.0.22. Alleen moet je wel bij elke clause de DESC meegeven, terwijl hij die volgens mij zou moeten overerven en je hem alleen de eerste keer zou moeten hoeven geven :?

Voor de mensen die de vraag niet goed lezen;
Hij zoekt een methode om zijn rows in dezelfde volgorde terug te krijgen, als de arrays'stonden waarmee hij de rows heeft opgevraagd.
Bij een input van array(12, 21, 43, 2, 9) wilt hij dus de rijen terug met de ID's op die volgorde.
Athans, zo heb ik het begrepen.

[ Voor 81% gewijzigd door frickY op 26-06-2006 16:28 ]


  • Dazzyon
  • Registratie: Oktober 2005
  • Laatst online: 13-10-2024

  • Cloud
  • Registratie: November 2001
  • Laatst online: 18-02 09:57

Cloud

FP ProMod

Ex-moderatie mobster

Ligt het aan mij, of leest werkelijk niemand nu de TS?

Hij zoekt een oplossing buiten PHP om en dus in de SQL query ten eerste. En een ORDER BY voorstellen is al helemaal gek als je het probleem van de TS begrijpt. :z
Hij wil zijn eigen array voorstellen op basis waarvan de result set gesorteerd moet worden, en dus niet gewoon een 1 -> 99 of 99 -> 1 sortering..

M.i. denk ik nog steeds dat dit niet mogelijk is binnen SQL in het algemeen, niet alleen MySQL.

Never attribute to malice that which can be adequately explained by stupidity. - Robert J. Hanlon
60% of the time, it works all the time. - Brian Fantana


Verwijderd

Topicstarter
Tjonge, wat een ophef in die paar minuten! Maar inderdaad: het ziet ernaar uit dat hier geen SQL-oplossing voor is...

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 17-02 09:21
Kan dus wel ;)

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 09-12-2025
Creatieve oplossing:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT
    *,
    CASE
        WHEN id = 1 THEN 2
        WHEN id = 2 THEN 3
        WHEN id = 3 THEN 1
    END AS sort_order
FROM
    objecten
WHERE
    id IN (1, 2, 3)
ORDER BY
    sort_order


Als je records met id (1, 2, 3) dus in volgorde (3, 1, 2) wilt sorteren. Je snapt het idee. Over performance weet ik niets.


Edit:

Zo mag hij ook:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
SELECT
    *
FROM
    objecten
WHERE
    id IN (1, 2, 3)
ORDER BY
    CASE
        WHEN id = 1 THEN 2
        WHEN id = 2 THEN 3
        WHEN id = 3 THEN 1
    END

[ Voor 23% gewijzigd door Michali op 26-06-2006 16:32 ]

Noushka's Magnificent Dream | Unity


  • riZZy
  • Registratie: Februari 2004
  • Nu online
Geen idee hoe het zit met de security, maar je zou wellicht ook de gewenste id's in een tijdelijke tabel kunnen schrijven met een variabele die de volgorde aangeeft. Vervolgens kun je dan een join maken tussen de 2 tabellen. Zo zou ik het aanpakken.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 19-02 19:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

wolkje schreef op maandag 26 juni 2006 @ 16:21:
Ligt het aan mij, of leest werkelijk niemand nu de TS?

Hij zoekt een oplossing buiten PHP om en dus in de SQL query ten eerste.
Dat vraagt hij idd, maar sinds wanneer is het hier op GoT een "u vraagt, wij draaien" cultuur? Hij zegt er namelijk achteraan: met de nodige optimalisaties

Of MySQL nou je data moet sorteren of PHP, er moet evenveel data opgehaald worden en evenveel gesorteerd worden. Er is dus zo goed als geen winst te halen. Sterker nog, de sorteermethode van de TS is zo specifiek dat je je in moeilijke bochten moet wringen om het in SQL voor elkaar te krijgen (zie het CASE voorbeeld van Michali of de tijdelijke tabel met JOIN van riZZy), waardoor het waarschijnlijk een stuk trager wordt dan de sortering in PHP zelf oplossen.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • riZZy
  • Registratie: Februari 2004
  • Nu online
Helemaal mee eens. Maar als we dan toch kritisch gaan doen; waarom zou je het in de eerste plaats willen? Ben benieuwd of je het probleem niet vooraf kunt oplossen....(lees: toch een sortering gebruiken op een variabele uit de tabel)

  • Cloud
  • Registratie: November 2001
  • Laatst online: 18-02 09:57

Cloud

FP ProMod

Ex-moderatie mobster

.oisyn schreef op maandag 26 juni 2006 @ 17:31:
[...]

Dat vraagt hij idd, maar sinds wanneer is het hier op GoT een "u vraagt, wij draaien" cultuur? Hij zegt er namelijk achteraan: met de nodige optimalisaties
Sinds nooit? :/ Dat was ook compleet niet wat ik bedoelde, maar er werden gewoon aan het begin dingen aangedragen waaruit bleek dat het probleem van de TS niet eens begrepen/gelezen werd. Dát was wat ik bedoelde :) Ik zou nooit zeggen (en deed dat dus ook niet) dat we meteen onze bak met kant-en-klare oplossingen open moeten trekken en de TS compleet moeten voorzien, dat is onzin.
Of MySQL nou je data moet sorteren of PHP, er moet evenveel data opgehaald worden en evenveel gesorteerd worden. Er is dus zo goed als geen winst te halen. Sterker nog, de sorteermethode van de TS is zo specifiek dat je je in moeilijke bochten moet wringen om het in SQL voor elkaar te krijgen (zie het CASE voorbeeld van Michali of de tijdelijke tabel met JOIN van riZZy), waardoor het waarschijnlijk een stuk trager wordt dan de sortering in PHP zelf oplossen.
Hier ben ik het met je eens :) De SQL query wordt onnodig veel complexer terwijl het prima in PHP code op te lossen is. Daarnaast denk ik dat de situatie te omzeilen is, door gewoon nog eens goed te kijken naar het geheel. De reden dat deze functionaliteit niet in SQL zit gebakken, is ook deels dat het blijkbaar nog nooit echt nodig is geweest, denk ik dan :) Je kunt vast wel zonder.

Never attribute to malice that which can be adequately explained by stupidity. - Robert J. Hanlon
60% of the time, it works all the time. - Brian Fantana


  • StevenK
  • Registratie: Februari 2001
  • Laatst online: 20:58
Ik zou een tweede tabel ernaast hangen, met daarin een id kolom en de waarden waarop je wilt sorteren; dan kun je de inner join van die twee tabellen sorteren zoals jij dat wilt.

Was advocaat maar vindt het juridische nog steeds leuk. Doet tegenwoordig iets in de metaal.


  • frickY
  • Registratie: Juli 2001
  • Laatst online: 17-02 09:21
.oisyn schreef op maandag 26 juni 2006 @ 17:31:
[...]
Sterker nog, de sorteermethode van de TS is zo specifiek dat je je in moeilijke bochten moet wringen om het in SQL voor elkaar te krijgen (zie het CASE voorbeeld van Michali of de tijdelijke tabel met JOIN van riZZy), waardoor het waarschijnlijk een stuk trager wordt dan de sortering in PHP zelf oplossen.
Zo omslachtig vind ik mijn - ook werkende - oplossing niet;
SQL:
1
ORDER BY ID = 12 DESC, ID = 6 DESC, ID = 9 DESC, ID = 21 DESC

Is eenvoudig op te bouwen met
PHP:
1
$sql = "ORDER BY ID = " . implode(" DESC, ID = ", $arrayMetIDs) . " DESC";

[ Voor 7% gewijzigd door frickY op 27-06-2006 09:01 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 19-02 19:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

Het is wel omslachtig en het performt voor geen meter, dus wat is precies je punt? Of voel je je genegeerd omdat ik jouw voorbeeld ook niet in mijn post heb genoemd? Hij past idd prima in dat rijtje thuis ja. Het rijtje van "please, don't do this" :)

[ Voor 52% gewijzigd door .oisyn op 27-06-2006 12:50 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1