Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1426 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  MySQL : forcer la position d'un résultat ?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

MySQL : forcer la position d'un résultat ?

n°2383997
vanquishV1​2
se coucher tard nuit
Posté le 06-05-2021 à 11:02:41  profilanswer
 

Hello !
 
Je voudrais savoir s'il est possible de forcer la position d'un résultat au sein d'une requête SQL.
 
Explication :
 
SELECT position, nom FROM produits ORDER BY position
 
donnerait:
 
Position,Nom
1,"Clio"
2,"Golf
3,"A3"
4,"Leon"
 
Et moi je voudrais forcer "A3" pour qu'il arrive en 2e, sans changer le reste.
Ainsi j'aurais en résultat :
1,"Clio"
3,"A3"
2,"Golf
4,"Leon"
 
La base fait plusieurs milliers de ligne.
 
Là ce sont des données d'exemple. Le vrai cas d'usage c'est de trier des produits par Chiffre d'affaire descendant mais pouvoir forcer, en position 3 par exemple, un produit même si son CA est faible
 
Merci !


---------------
Bha ouais mais bon, m'enfin quoi...
mood
Publicité
Posté le 06-05-2021 à 11:02:41  profilanswer
 

n°2384036
antac
..
Posté le 06-05-2021 à 13:05:17  profilanswer
 

Oui, tu peux faire un truc comme ça :
SELECT IIF(position='A3',-1,position) as position, nom
FROM produits
ORDER BY position

n°2384064
vanquishV1​2
se coucher tard nuit
Posté le 06-05-2021 à 16:20:05  profilanswer
 

Merci !

 

Et si je veux pouvoir en forcer 2 par exemple ?
Là ce que tu as fait c'est de remonter d'une place le "A3"?
Moi je voudrais forcer "A3" en position 2, quelle que soit sa position initiale
Et pouvoir le faire sur plusieurs entrées

 

Merci beaucoup ;)

Message cité 1 fois
Message édité par vanquishV12 le 06-05-2021 à 16:31:09

---------------
Bha ouais mais bon, m'enfin quoi...
n°2384068
mechkurt
Posté le 06-05-2021 à 16:40:34  profilanswer
 

Si tu as une sélection plus complexe tu devrais plutôt utiliser case :
https://dev.mysql.com/doc/refman/5.7/en/case.html
 
Exemple :

Code :
  1. SELECT
  2.     CASE nom
  3.         WHEN 'A3' THEN 1.9
  4.         WHEN 'Golf' THEN 2.9
  5.         ELSE position
  6.     END CASE
  7.     AS position,
  8.     nom
  9. FROM produits ORDER BY position


Par contre ne forçant des positions tu risque d'avoir des conflits avec des égalités de position (c'est pourquoi au lieu de mettre 2 et 3 j'ai mis 1.9 et 2.9, de cette manière il seront bien avant l'éventuel équivalent).


---------------
D3
n°2384070
vanquishV1​2
se coucher tard nuit
Posté le 06-05-2021 à 16:59:14  profilanswer
 

Super cool merci


---------------
Bha ouais mais bon, m'enfin quoi...
n°2384071
antac
..
Posté le 06-05-2021 à 16:59:49  profilanswer
 

vanquishV12 a écrit :

Merci !
 
Et si je veux pouvoir en forcer 2 par exemple ?
Là ce que tu as fait c'est de remonter d'une place le "A3"?  
Moi je voudrais forcer "A3" en position 2, quelle que soit sa position initiale
Et pouvoir le faire sur plusieurs entrées
 
Merci beaucoup ;)


Non, ce que je fais c'est forcer la première position à A3 (position "-1" ) qui sera toujours avant n'importe quelle autre position.  

n°2384072
mechkurt
Posté le 06-05-2021 à 17:08:05  profilanswer
 

Je ne connaissais pas IIF(), du coups j'ai pensé que c'était un position-1 implicite.
 
Il faudrait ptet que tu gères un vrai compteur car à l'heure actuel tu es complétement sûr de ta colonne position (incrément partant de 1 et sans trou) ?


---------------
D3
n°2384083
vanquishV1​2
se coucher tard nuit
Posté le 06-05-2021 à 18:26:42  profilanswer
 

Alors non, en fait, ce n'est même pas sur position que je dois trier, en y réfléchissant, mais sur "CA" (chiffre d'affaire) et là bha, ça va de 0 à plusieurs centaines de milliers, parfois avec des virgules

 

PS : super pour IIF, je pensais que c'était une faute de frappe au départ


Message édité par vanquishV12 le 06-05-2021 à 18:33:10

---------------
Bha ouais mais bon, m'enfin quoi...
n°2384098
antac
..
Posté le 06-05-2021 à 19:58:29  profilanswer
 

mechkurt a écrit :

Je ne connaissais pas IIF(), du coups j'ai pensé que c'était un position-1 implicite.
 
Il faudrait ptet que tu gères un vrai compteur car à l'heure actuel tu es complétement sûr de ta colonne position (incrément partant de 1 et sans trou) ?


En fait je crois que c'est assez spécifique à SQL Server mais Grosso modo c'est comme un case...  
 

n°2384183
vanquishV1​2
se coucher tard nuit
Posté le 07-05-2021 à 11:22:50  profilanswer
 

Du coup le fait que mes "numéros" ne se suivent pas change la méthode à utiliser ?


---------------
Bha ouais mais bon, m'enfin quoi...
mood
Publicité
Posté le 07-05-2021 à 11:22:50  profilanswer
 

n°2384303
mechkurt
Posté le 07-05-2021 à 16:35:34  profilanswer
 

Ça vas être nettement plus compliquer d'intercaler des valeurs fixe de position si tu ne connait pas les valeurs de tri de la colonne renvoyé à l'avance (mettre avant ou après serait simple mais là non).
Faut que tu gères une variable (et donc une procédure), avec peut être en plus une sous requête...
 
...c'est loin d'être anodin, ce serait ptet plus simple (si tu le peux) de faire ce traitement dans ton langage de programmation favoris  ^^


---------------
D3
n°2384373
antac
..
Posté le 07-05-2021 à 20:35:32  profilanswer
 

Au final... c'est quoi l'intérêt ?

n°2384478
vanquishV1​2
se coucher tard nuit
Posté le 08-05-2021 à 14:47:30  profilanswer
 

Trier par CA DESC mais forcer la mise en avant de 4 ou 5 produits en haut de listing, quel que soit leur CA


---------------
Bha ouais mais bon, m'enfin quoi...
n°2384479
vanquishV1​2
se coucher tard nuit
Posté le 08-05-2021 à 14:48:50  profilanswer
 

mechkurt a écrit :

Ça vas être nettement plus compliquer d'intercaler des valeurs fixe de position si tu ne connait pas les valeurs de tri de la colonne renvoyé à l'avance (mettre avant ou après serait simple mais là non).
Faut que tu gères une variable (et donc une procédure), avec peut être en plus une sous requête...
 
...c'est loin d'être anodin, ce serait ptet plus simple (si tu le peux) de faire ce traitement dans ton langage de programmation favoris  ^^


En fait j’ai mal répondu
Je trie par ÇA mais j’ai bien une autre colonne avec des id


---------------
Bha ouais mais bon, m'enfin quoi...
n°2384480
antac
..
Posté le 08-05-2021 à 17:31:49  profilanswer
 

vanquishV12 a écrit :

Trier par CA DESC mais forcer la mise en avant de 4 ou 5 produits en haut de listing, quel que soit leur CA


Dans ce cas, pourquoi ne pas faire une requête avec tes 4 ou 5 produits et un UNION avec une autre requête avec ton tri en excluant les 4/5 produits précédents.  

n°2384504
vanquishV1​2
se coucher tard nuit
Posté le 08-05-2021 à 23:05:38  profilanswer
 

Justement les 4 ou 5 produits ne sont pas forcément les premiers
 
Ils peuvent être positionnés la ou on veut  
Et ça peut être 0, 1 , 2, 10 produits dont on force la position
 
Je sais pas si c’est clair ?


---------------
Bha ouais mais bon, m'enfin quoi...
n°2384507
antac
..
Posté le 09-05-2021 à 00:04:45  profilanswer
 

Si mais franchement, le mieux est de gérer ça côté programmation je pense.

n°2384570
mechkurt
Posté le 09-05-2021 à 22:48:18  profilanswer
 

antac a écrit :

Si mais franchement, le mieux est de gérer ça côté programmation je pense.


+1


---------------
D3
n°2384571
flo850
moi je
Posté le 09-05-2021 à 23:21:36  profilanswer
 

tu ajoutes une colonne favorite ( 0, 1)
 
et tu fais order by favorite desc, position


---------------

n°2384572
mechkurt
Posté le 09-05-2021 à 23:41:02  profilanswer
 

Sauf que là les favorites seront avant, lui il veut les intercaler a des places "fixe" genre 2ème ou 4ème sans savoir avant les valeurs retourné par son ORDER BY...


---------------
D3
n°2384575
pluj
Posté le 10-05-2021 à 00:35:29  profilanswer
 

Salut,
 

Citation :

Et ça peut être 0, 1 , 2, 10 produits dont on force la position


Elles ne sont pas identifiées et déterminées autrement que par leurs noms ? De façon à pouvoir le réaliser directement via ORDER ?
 
En l'état, je ne vois que ce genre de démarche :
 

Code :
  1. $count = SELECT COUNT(*) FROM produits /*WHERE nom <> 'A3'*/;
  2.  
  3. SELECT * FROM produits WHERE nom <> 'A3' LIMIT 0, 1 ORDER BY nom
  4. UNION
  5. SELECT * FROM produits WHERE nom = 'A3'
  6. UNION
  7. SELECT * FROM produits WHERE nom <> 'A3' LIMIT 1, $count - 2 ORDER BY nom


 
Avec plusieurs produits à positions forcées, je laisse imaginer la complexité (avec la propriété d'UNION on pourrait éventuellement supprimer les clauses WHERE et LIMIT de la dernière)
 

Citation :

tu ajoutes une colonne favorite ( 0, 1)


 
Une colonne avec cette position forcée (sinon NULL) et la comparer au ROW_NUMBER ?
 

Code :
  1. SELECT *
  2. FROM(
  3.    SELECT ROW_NUMBER() rn, p.*
  4.    FROM produits p
  5. ) t
  6. ORDER BY NULLIF(position_forcee, rn), position_forcee IS NULL


Message édité par pluj le 10-05-2021 à 00:57:41
n°2384580
rufo
Pas me confondre avec Lycos!
Posté le 10-05-2021 à 08:32:37  profilanswer
 

vanquishV12 a écrit :

Trier par CA DESC mais forcer la mise en avant de 4 ou 5 produits en haut de listing, quel que soit leur CA


Ah ben tiens, j'ai fait ça y'a pas longtemps pour un forum : trier les sujets par la date de dernier message posté mais avec certains sujets qui ont un rang de 1 à n que je veux mettre en top de ma liste de sujet.
 
J'ai fait une requête SQL avec un UNION : dans la première partie de la requête, les sujets ayant un rang et dans la seconde parte, les sujets n'en ayant pas.
Edit : voici le genre de requête que ça donne :

Citation :


SELECT rkt.ForumTopicID, rkt.ForumTopicTitle, rkt.ForumTopicRank, rkt.ForumMessageID, rkt.LastTopicForumMessageDate,  
@rownum := @rownum + 1 AS TopicPos  
FROM  
     (SELECT ft.ForumTopicID, ft.ForumTopicTitle, ft.ForumTopicRank, fm.ForumMessageID, fm.ForumMessageDate AS LastTopicForumMessageDate
      FROM ForumTopics ft, ForumMessages fm,  
             (select @rownum := 0) AS r,  
             (SELECT tfm.ForumTopicID, MAX(tfm.ForumMessageID) AS LastTopicMessageID  
             FROM ForumMessages tfm GROUP BY tfm.ForumTopicID) AS LastMsgs  
      WHERE ft.ForumTopicID = fm.ForumTopicID AND ft.ForumTopicID = LastMsgs.ForumTopicID  
                        AND LastMsgs.LastTopicMessageID = fm.ForumMessageID AND ft.ForumTopicRank IS NOT NULL  
      ORDER BY ft.ForumTopicRank) AS rkt  
UNION  
SELECT rkt.ForumTopicID, rkt.ForumTopicTitle, rkt.ForumTopicRank, rkt.ForumMessageID, rkt.LastTopicForumMessageDate,  
@rownum := @rownum + 1 AS TopicPos  
FROM  
     (SELECT ft.ForumTopicID, ft.ForumTopicTitle, ft.ForumTopicRank, fm.ForumMessageID, fm.ForumMessageDate AS LastTopicForumMessageDate
      FROM ForumTopics ft, ForumMessages fm,
               (select @rownum := 0) AS r,  
               (SELECT tfm.ForumTopicID, MAX(tfm.ForumMessageID) AS LastTopicMessageID  
                FROM ForumMessages tfm GROUP BY tfm.ForumTopicID) AS LastMsgs  
      WHERE ft.ForumTopicID = fm.ForumTopicID AND ft.ForumTopicID = LastMsgs.ForumTopicID  
                 AND LastMsgs.LastTopicMessageID = fm.ForumMessageID AND ft.ForumTopicRank IS NULL  
      ORDER BY LastTopicForumMessageDate DESC) AS rkt  
GROUP BY rkt.ForumTopicID ORDER BY TopicPos


Le truc intéressant, c'est le (select @rownum := 0) AS r dans le FROM et le @rownum := @rownum + 1 AS TopicPos dans le SELECT.


Message édité par rufo le 10-05-2021 à 10:09:48

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
n°2384605
vanquishV1​2
se coucher tard nuit
Posté le 10-05-2021 à 10:05:11  profilanswer
 

Pfouuaa la requête ^^
 
Merci
 
Je vois que c'est compliqué. Merci pour toutes ces réponses
La raison pour laquelle je veux faire ça en SQL c'est que pour l'usage que j'en ai, on veut absolument éviter de toucher au code et tout faire en SQL, pour plein de raisons surtout internes/liées au contexte


---------------
Bha ouais mais bon, m'enfin quoi...
n°2384608
rufo
Pas me confondre avec Lycos!
Posté le 10-05-2021 à 10:10:48  profilanswer
 

Je viens de la simplifier en virant les champs qui servent à rien pour ton pb. ;)
 
Edit : tu remarqueras que le contenu du 1er SELCT au niveau du UNION est identique tout comme les 2 FROM. Ce qui change, c'est dans le WHERE avec dans la première partie (avant le UNION, tu as "AND ft.ForumTopicRank IS NOT NULL" et dans l'autre, tu as ft.ForumTopicRank IS NULL. Il ya aussi le ORDER BY : dans le premier, tu as ORDER BY ft.ForumTopicRank alors que dans la 2ème partie du UNION, tu as ORDER BY LastTopicForumMessageDate DESC
En gros, si je résume la requête :
SELECT mes topics, position calculée
FROM mes tables
WHERE mes critères AND Topics avec un rang
ORDER BY rang ASC
UNION
SELECT mes topics, position calculée
FROM mes tables
WHERE mes critères AND Topics sans rang
ORDER BY date de dernier message posté DESC
le tout ORDER BY position calculée
 
La, position calculée l'est grâce à cette table temporaire (select @rownum := 0) AS r qui initialise ma variable @rownum à 0 et dans le select, chaque enregistrement affichée incrémente de 1 ma variable @rownum. Comme les topics avec un rang sont dans la partie avant le UNION, ils sortent en premier car ils auront la valeur de leur variable @rownum plus faible que pour les topics qui sortent via la 2ème partie du UNION.


Message édité par rufo le 10-05-2021 à 10:18:20

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
n°2384631
vanquishV1​2
se coucher tard nuit
Posté le 10-05-2021 à 11:20:50  profilanswer
 

Un grand merci !


---------------
Bha ouais mais bon, m'enfin quoi...
mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  MySQL : forcer la position d'un résultat ?

 

Sujets relatifs
Javascript API / Recuperer le resultat[MySQL] Order by sur caractères spéciaux
MySql indisponible ce matinSauvegarde de bases MySQL
[PHP/MySQL] PDO - bindValue ça bind pas[MySQL] MAJ d'une table avec trigger et conditions
[Linux Shell] forcer un exit 0 sur un find[MySQL] Table obèse
Fonction qui compare deux tableaux et stocke le résultat dans un troisInstallation MySQL
Plus de sujets relatifs à : MySQL : forcer la position d'un résultat ?


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR