Critère `par_ordre_liste` et ordre des éléments pas dans la `#LISTE` #5273

Closed
opened 2 months ago by cy.altern · 9 comments
Owner

le critère de tri SPIP par_ordre_liste a un gros défaut : si on l'applique sur un ensemble d'éléments qui ne sont pas tous dans la #LISTE passée en 2ème paramètre, il affiche d'abord les éléments hors de la #LISTE puis ceux qui sont dedans.
Exemple si on a 16 sites syndiqués dans la BDD :

<BOUCLE_t(SYNDIC){par_ordre_liste id_syndic, #LISTE{14,16,13}}{id_syndic > 10}>

retourne les sites dans l'ordre suivant : 11, 12, 15, 14, 16, 13
La requête SQL passée est :

SELECT * FROM spip_syndic AS syndic 
WHERE syndic.id_rubrique > 10
ORDER BY FIELD (syndic.id_syndic, 14,16,13);

Pour obtenir le résultat "naturellement attendu" (i.e. d'abord ceux de la liste puis les autres) il faudrait utiliser la requête SQL suivante :

SELECT * FROM spip_syndic AS syndic 
WHERE syndic.id_rubrique > 10
ORDER BY IF (FIELD(syndic.id_syndic, 14,16,13)=0,1,0), FIELD(syndic.id_syndic,14,16,13);

Ref : https://dba.stackexchange.com/questions/109120/how-does-order-by-field-in-mysql-work-internally pour la très astucieuse utilisation du IF (FIELD ... en premier critère de la requète

le critère de tri SPIP `par_ordre_liste` a un gros défaut : si on l'applique sur un ensemble d'éléments qui ne sont pas tous dans la `#LISTE` passée en 2ème paramètre, il affiche *d'abord* les éléments hors de la `#LISTE` *puis* ceux qui sont dedans. Exemple si on a 16 sites syndiqués dans la BDD : ``` <BOUCLE_t(SYNDIC){par_ordre_liste id_syndic, #LISTE{14,16,13}}{id_syndic > 10}> ``` retourne les sites dans l'ordre suivant : `11, 12, 15, 14, 16, 13` La requête SQL passée est : ``` SELECT * FROM spip_syndic AS syndic WHERE syndic.id_rubrique > 10 ORDER BY FIELD (syndic.id_syndic, 14,16,13); ``` Pour obtenir le résultat "naturellement attendu" (i.e. *d'abord* ceux de la liste *puis* les autres) il faudrait utiliser la requête SQL suivante : ``` SELECT * FROM spip_syndic AS syndic WHERE syndic.id_rubrique > 10 ORDER BY IF (FIELD(syndic.id_syndic, 14,16,13)=0,1,0), FIELD(syndic.id_syndic,14,16,13); ``` _Ref : https://dba.stackexchange.com/questions/109120/how-does-order-by-field-in-mysql-work-internally pour la très astucieuse utilisation du `IF (FIELD ...` en premier critère de la requète_
cy.altern added the
amélioration
label 2 months ago
b_b added this to the 4.2 milestone 2 months ago
Owner

Je ne sais pas comment avait été pensé ce critère, mais peut être que ça devrait être le comportement par défaut non ?

Je ne sais pas comment avait été pensé ce critère, mais peut être que ça devrait être le comportement par défaut non ?
Owner

Et c’est valide en SQLIte le IF FIELD ?

Et c’est valide en SQLIte le IF FIELD ?
Owner

Alors je réponds : dans mes usages pour x raisons je n'avais pas ce cas là, et donc c'est un oubli. Je pense qu'il est naturel que les ids qui sont pas dans la liste fournie soient rejetés à la fin, sans avoir à traiter via une option du critere

(à la limite, on peut ajouter un critere {par_in_liste ..} qui trie en mettant d'abord ceux dans la liste puis ensuite ceux en dehors de la liste, ce qui permet au besoin de bidouiller pour forcer l'un ou l'autre des cas).

Pour le critère, je pense qu'on peut faire encore mieux en générant (dans l'exemple ci-dessus) un

ORDER BY -FIELD (syndic.id_syndic, 13,16,14);

(on mets un - devant et on reverse l'ordre de la liste), ce qui évite un double FIELD et in IF)

Alors je réponds : dans mes usages pour x raisons je n'avais pas ce cas là, et donc c'est un oubli. Je pense qu'il est naturel que les ids qui sont pas dans la liste fournie soient rejetés à la fin, sans avoir à traiter via une option du critere (à la limite, on peut ajouter un critere `{par_in_liste ..}` qui trie en mettant d'abord ceux dans la liste puis ensuite ceux en dehors de la liste, ce qui permet au besoin de bidouiller pour forcer l'un ou l'autre des cas). Pour le critère, je pense qu'on peut faire encore mieux en générant (dans l'exemple ci-dessus) un ``` ORDER BY -FIELD (syndic.id_syndic, 13,16,14); ``` (on mets un `-` devant et on reverse l'ordre de la liste), ce qui évite un double `FIELD` et in `IF`)
Collaborator
ORDER BY -FIELD (syndic.id_syndic, 13,16,14);

(on mets un - devant et on reverse l'ordre de la liste), ce qui évite un double FIELD et in IF)

J'ai testé la requete avec cette option, ca ne fonctionne pas chez moi.

> ``` > ORDER BY -FIELD (syndic.id_syndic, 13,16,14); > ``` > (on mets un `-` devant et on reverse l'ordre de la liste), ce qui évite un double `FIELD` et in `IF`) J'ai testé la requete avec cette option, ca ne fonctionne pas chez moi.
Collaborator

Je ne sais pas comment avait été pensé ce critère, mais peut être que ça devrait être le comportement par défaut non ?

Oui, je m'attendais à ce comportement. J'ai préféré ajouter un argument pour ne pas casser l'existant.

> Je ne sais pas comment avait été pensé ce critère, mais peut être que ça devrait être le comportement par défaut non ? Oui, je m'attendais à ce comportement. J'ai préféré ajouter un argument pour ne pas casser l'existant.
Owner

@tofulm attention a bien faire inverser les numéros (array_reverse) : 14,16,13 => 13,16,14 pour ton test.

@tofulm attention a bien faire inverser les numéros (array_reverse) : 14,16,13 => 13,16,14 pour ton test.
Collaborator

@tofulm attention a bien faire inverser les numéros (array_reverse) : 14,16,13 => 13,16,14 pour ton test.

Oups, merci ça fonctionne mieux !

> @tofulm attention a bien faire inverser les numéros (array_reverse) : 14,16,13 => 13,16,14 pour ton test. Oups, merci ça fonctionne mieux !
Owner

Tu reproposes ta PR du coup @tofulm ? A priori pas besoin de paramètre en plus si on est tous d’accord sur le comportement attendu ?

Tu reproposes ta PR du coup @tofulm ? A priori pas besoin de paramètre en plus si on est tous d’accord sur le comportement attendu ?
Owner

Appliqué en dev, reporté en 4.1

Appliqué en dev, reporté en 4.1
marcimat closed this issue 1 month ago
Sign in to join this conversation.
No Milestone
No project
No Assignees
4 Participants
Notifications
Due Date

No due date set.

Dependencies

This issue currently doesn't have any dependencies.

Loading…
There is no content yet.