2009-07-17 5 views
5

J'ai créé une table. Dans un domaine, j'ai une priorité de cet enregistrement (entre 1-9). Je n'ai pas défini de priorité pour tous les enregistrements, donc pour certains enregistrements, il restera nul. Lorsque j'affiche ces enregistrements dans ma page HTML, je vérifie simplement ces priorités - si la priorité existe, alors je vais l'afficher tel quel, si elle est nulle, alors je l'afficherai comme la priorité la plus basse de '10' (juste pour l'affichage).Est-il possible d'utiliser à la fois l'ordre par et où dans une seule requête

Le problème se produit lors du tri de la table. Si j'essaie de sort(DESC) le tableau, il affiche le 10 dans la première rangée et continue plus tard parfaitement (1,2, ....).

Comment résoudre ce problème?

Est-il possible d'afficher les priorités d'abord et plus tard continuer avec les valeurs nulles?

+0

Pouvez-vous fournir toute requête SQL que vous êtes en utilisant? –

+0

Sélectionnez la priorité à partir de la commande prioritaire par priorité desc – praveenjayapal

Répondre

2

Il existe plusieurs façons de résoudre ce problème.

1/Modifier les données de telle sorte que 10 est en fait dans le tableau (plutôt que NULL):

update table TBL set FLD = 10 where FLD is null; 

2/Modifier votre requête pour renvoyer des valeurs différentes pour NULL:

select FLD1, FLD2, case where FLD3 is null then 10 else FLD3 end from ... 

3/Créer une vue pour faire l'option 2 ci-dessus automagiquement.

J'aurais tendance à opter pour l'option 1, car c'est probablement la plus efficace. SQL ne spécifie pas comment les NULL sont triés (bien que je pense qu'il spécifie qu'ils doivent être adjacents) - cela signifie qu'ils pourraient être au début ou à la fin (ou éventuellement au milieu si je n'ai jamais vu cela se produire).

La raison pour laquelle j'aborde l'aspect de l'efficacité est que les fonctions par ligne ne se développent pas bien. Au fur et à mesure que la table grossit, vous constaterez que la conversion de valeurs NULL en 10 chaque fois que vous sélectionnez sera très coûteuse.

Il est préférable de ne pas hésiter et de les mettre à 10 dans la base de données. Cela permettra au SGBD d'optimiser les requêtes. Et, si jamais vous avez besoin d'utiliser 10 pour un autre niveau de priorité réel, changez simplement tous les 10 actuels en 11 (ou 9999) avant de commencer.

4

Voici un court exemple qui montre comment convertir NULL en une valeur de puis tri sur elle ..

create table test 
(
    priority int null, 
    detail varchar(10) 
) 

insert into test values (1, 'one') 
insert into test values (3, 'three') 
insert into test values (8, 'eight') 
insert into test values (9, 'nine') 
insert into test values (null, 'ten') 

select ISNULL(priority, 10), detail from test order by ISNULL(priority, 10) 

La clé est ISNULL'ing le champ de valeur null'able pour convertir NULL à la valeur de (10) que vous voulez.

+0

Cela convient aux tables plus petites, sachez que les fonctions par ligne ne sont pas bien adaptées. – paxdiablo

+1

Dans le meilleur sens possible, "déchets" - j'ai travaillé sur un système où il y a eu des null dans les tables qui sont considérablement plus larges et considérablement plus longues (c.5 + million d'enregistrements) et les performances ont été plus qu'adéquates (ce qui inclut les données utilisées dans les requêtes de jointure complexes). C'était avec Sql Server 2000, j'imagine que 2k5/2k8 serait aussi bon, sinon meilleur. MySql d'autre part - bien, ça fait peu de bien, donc qui sait ;-) – Rob

+0

Je viens d'effectuer un micro-benchmark sur ce (table 2 colonnes, 655k lignes, 20% avec priorité comme nulle, 80% partage égal entre [1,3,8,9}) et plus de 4 exécutions de chacun, il n'y avait pas de différence significative dans la performance. – Rob

1

Si vous voulez des enregistrements avec priorité NULL apparaissent dernière, je recommanderais quelque chose comme

ORDER BY (IFNULL (priorité, 1000000)) ou quelque chose comme ça

+1

Les utilisateurs finiront par insérer des enregistrements avec la priorité 1000001. Je le ferais avec 'ORDER BY CASE WHEN Priority est NULL ALORS 1 ELSE 0 END, Priority' juste pour être sûr. – wqw

Questions connexes