web-dev-qa-db-fra.com

COMMANDER PAR ASC avec Nulls en bas

J'écris une requête SQL qui connecte une table des écoles à une table des districts. Une relation simple à plusieurs où chaque école est rattachée à un district. Ma requête est la suivante:

SELECT 
    schools.id AS schoolid,
    schools.name AS school, 
    districts.id AS districtid, 
    districts.name AS district
FROM sms_schools AS schools
    LEFT JOIN sms_districts AS districts ON schools.districtid = districts.id
WHERE 1 = 1
ORDER BY districts.name, schools.name

La raison pour laquelle j'ai fait un joint gauche est parce que toutes les écoles ne sont pas rattachées à un district. Par exemple, une école peut être scolarisée à domicile et peut contenir tous les élèves qui sont scolarisés à domicile. Ce ne serait pas dans un quartier.

Donc, ce que je voudrais faire, c'est utiliser la commande ORDER BY pour commander car c'est par nom de district puis par nom d'école. Le seul problème est que je veux que le district nul soit en bas pour que je puisse ensuite utiliser un groupe appelé "Autre" à la fin de ma sortie.

Est-il possible de classer par ordre croissant de null à la fin de la sortie?

38
Dave Long

Seulement 1 minute après avoir posé la question, j'ai trouvé ma réponse. Dans le cas d'utilisation de la clause order by, les valeurs null ont une valeur plus élevée que toute autre chose:

 ORDER BY (CASE WHEN districts.id IS NULL then 1 ELSE 0 END),districts.name, schools.name;
38
Dave Long

Vous pouvez utiliser la fonction ISNULL().

Dans le manuel MySQL:

ISNULL (expr)

Si expr est NULL, ISNULL() renvoie 1, Sinon il renvoie 0.

Par exemple :

ORDER BY ISNULL(districts.name), districts.name, schools.name

J'aime utiliser ceci au lieu de l'option CASE pour MySQL. Sachez simplement que ce n'est pas portable puisque ISNULL() n'est pas du SQL standard et fonctionne différemment dans les autres versions de SQL.

25
toxalot

Les valeurs nulles par défaut se produisent en haut, mais vous pouvez utiliser IsNull pour attribuer des valeurs par défaut, qui le mettront à la position souhaitée ...


SELECT schools.id AS schoolid,schools.name AS school, districts.id AS districtid, districts.name AS district FROM sms_schools AS schools LEFT JOIN sms_districts AS districts ON schools.districtid = districts.id WHERE 1 = 1 
ORDER BY isnull(districts.name,'1'), schools.name 
5
M.R.
SELECT
 schools.id AS schoolid,
 schools.name AS school,
 districts.id AS districtid,
 districts.name AS district,
 if(schools.districtid IS NULL,1,0) as sort 
FROM sms_schools AS schools
LEFT JOIN sms_districts AS districts 
 ON schools.districtid = districts.id
WHERE 1 = 1
ORDER BY sort, districts.name, schools.name

mettre plus de règles de tri à l'intérieur du 'nouveau' colunm et utiliser n'importe quel nombre masquer le champ dans votre code, tester s'il est possebele de trier sur le if directement (ordre par if ...)

bonne chance

2
borrel