8768 sujets

Développement web côté serveur, CMS

Bonjour,
Question certainement simple pour qui manie régulièrement Mysql.

J'ai une table qui liste des personnes avec, entre autres, le département dans lequel elles travaillent (disons : direction, production, services généraux...)

J'ai besoin d'afficher cette liste avec comme ordre :
- le directeur ('id'='2')
- les autres membres de la direction par ordre alphabétique ('dpt'='direction' sauf 'id'='2')
- puis tous les autres ('dpt'!='direction').

J'arrive à éxécuter chaque requête séparément. Mais comment les réunir en 1 résultat qui respecte cet ordre ?

Merci.
Modifié par jlba (19 Oct 2022 - 11:46)
Modérateur
Bonjour,

On peut ajouter un champ bidon (ci-dessous "rank") qui aura une valeur différente pour chaque SELECT (ci-dessous respectivement 1, 2 et 3). On fait alors une union des trois SELECT de base (tes SELECT qui marchent déjà auxquels on rajoute le champ "rank" mentionné ci-dessus), puis un SELECT global sur le résultat de l'union des trois SELECT. C'est ce SELECT global qui fera un tri principal en utilisant la valeur de "rank" pour que tes 3 listes apparaissent les unes derrière les autres, puis un tri secondaire alphabétique sur les noms des personnes.

Par exemple :
select *
from (
    select 1 as rank, id, nom, dpt from uneTable WHERE id="2"
    union all
    select 2 as rank, id, nom, dpt from uneTable WHERE dpt="direction" AND id!="2"
    union all
    select 3 as rank, id, nom, dpt from uneTable WHERE dpt!="direction" AND id!="2" 
) as a
order by rank, nom


uneTable doit être remplacée par le nom de ta table.
id, nom, dpt peuvent être complétés par tous les champs que tu veux.
as a après la parenthèse fermante du FROM défini un alias (qui peut être n'importe quel mot) pour le SELECT et c'est nécessaire.

Amicalement,
bonjour,

Tu peux aussi trier sur un ordre dynamique en fonction de tes conditions:

SELECT a.*
CASE 
    when id = 2 then 1
    when dpt='direction' and id != 2 then 2
else 99  end as ordre
FROM agents a
order by ordre

Ou


SELECT *
FROM agents 
order by CASE 
    when id = 2 then 1
    when dpt='direction' and id != 2 then 2
else 99  end

Modifié par loicbcn (19 Oct 2022 - 08:53)
Merci de vos réponses.

Juste une question : pourquoi 99 dans la 3ème solution ? Est-ce que 3 ne serait pas suffisant ?
Modérateur
Bonjour,

Dans la 1er proposition de loicbcn ci-dessus, il manque une virgule après a.*, et à la fin, après "ordre", on peut ajouter une virgule suivi du nom d'un autre champ (par exemple "nom") pour faire un tri secondaire alphabétique sur le nom des gens.
SELECT a.*,
CASE 
    when id = 2 then 1
    when dpt='direction' and id != 2 then 2
    else 99 END as ordre
FROM agents a
order by ordre, nom


Dans la 2e proposition de loicbcn ci-dessus, on peut ajouter à la fin après "end" une virgule suivi du nom d'un autre champ (par exemple "nom") pour faire un tri secondaire alphabétique sur le nom des gens.
SELECT *
FROM agents 
order by CASE 
    when id = 2 then 1
    when dpt='direction' and id != 2 then 2
    else 99 END, nom

Et "agents" et "nom" doivent bien sûr être remplacés respectivement par le nom de ta table des personnes et le nom du champ contenant le nom des personnes.

Amicalement
Meilleure solution
Modérateur
jlba a écrit :
Merci de vos réponses.

Juste une question : pourquoi 99 dans la 3ème solution ? Est-ce que 3 ne serait pas suffisant ?


Oui, 3, ça va aussi.

Amicalement,
parsimonhi a écrit :
Bonjour,
Dans la 2e proposition de loicbcn ci-dessus, on peut ajouter à la fin après "end" une virgule suivi du nom d'un autre champ (par exemple "nom") pour faire un tri secondaire alphabétique sur le nom des gens.
SELECT *
FROM agents 
order by CASE 
    when id = 2 then 1
    when dpt='direction' and id != 2 then 2
    else 99 END, nom

Et "agents" et "nom" doivent bien sûr être remplacés respectivement par le nom de ta table des personnes et le nom du champ contenant le nom des personnes.
Amicalement


Merci de ces précisions.
J'ai repris cette dernière option en ajoutant
WHERE publication=1
avant le
order by case
.