IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

[Access] Tri des données


Sujet :

Langage SQL

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 9
    Points : 2
    Points
    2
    Par défaut [Résolu] [Access] Tri des données
    Bonjour à tous

    J'ai une question sans doute très basique, mais je débute et je n'ai pas trouvé la réponse dans le très bon cours de ce site.
    Voici ma question : imaginons une table MYTAB à 2 colonnes, la première (NOMBRE) contient des nombres de 1 à 10, la seconde (TEXTE) contient du texte "Un", "Deux"... "Dix" dans l'ordre.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    NOMBRE     TEXTE
    ---------------------
    1               Un
    2               Deux
    3               Trois
    4               Quatre
    ...
    10             Dix

    Je veux une requête pour récupérer le contenu de la colonne TEXTE en fonction de valeurs contenues dans la colonne NOMBRE, sachant que NOMBRE contenir plusieurs valeurs dans un ordre donné (voir exemple). J'arrive à récupérer les bons éléments, mais pas dans le bon ordre, et j'ai l'impression que la commande ORDER BY ne peut pas répondre à mon problème.
    Mon but est d'avoir le résultat en 1 seul requête car je fais cette requête depuis un logiciel de simulation qui dispose de capacités très limitées pour récupérer des données depuis une base de données, et chaque requête est relativement lente, je veux donc limiter au maximum leur nombre. La base de données est de type Oracle.

    Exemple : Je veux récupérer "Deux" "Huit" "Cinq" dans cet ordre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT TEXT FROM MYTAB WHERE NOMBRE IN (2,8,5)
    Le résultat renvoyé est "Deux" "Cinq" "Huit", sans doute parce que ces entrées apparaissent dans cet ordre dans la base. ORDER BY ne semble pas pouvoir être utilisé dans ce cas car il se base sur un ordre établi sur une colonne de la table, or la je veux un classement en fonction de l'ordre dans IN (...).
    Y'a-t il un moyen d'obtenir ça facilement ? avec des sous-requêtes peut-être?

    Merci par avance et toutes mes excuses si la réponse est dans le cours et que je suis passé à côté..

  2. #2
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    Salut,
    A mon avis il faut utiliser une colonne fictive pour créer un ordre par nombre, unir les résultats et enfin les trier selon cet ordre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT TEXT, 1 as ordre FROM MYTAB WHERE NOMBRE = 2
    UNION ALL
    SELECT TEXT, 2 as ordre FROM MYTAB WHERE NOMBRE = 8
    UNION ALL
    SELECT TEXT, 3 as ordre FROM MYTAB WHERE NOMBRE = 5
    order by ordre
    Mais je ne sais pas si cette solution peut te convenir.
    Bon c'est peut être possible de créer la colonne ordre tout en évitant les UNION ALL, mais ça restera peu intuitif.

  3. #3
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    salut,

    quel SGBD utilises tu?

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Cybher Voir le message
    salut,

    quel SGBD utilises tu?

    La base de données est sous Oracle (je ne connais pas la version précise, c'est le service informatique qui gère ca, mais je peux me renseigner si besoin), le logiciel que j'utilise pour lancer la requête est acslXtreme (un logiciel de simulation dynamique genre Matlab) qui possède une petite fonction pour récupérer des données via une requête SQL (il tourne sous Windows et fait sans doute en appel à des composants de Windows pour gérer ces requêtes mais je n'en sais pas plus).

  5. #5
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    salut,

    tu peux essayer ceci peut etre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    order by field(nombre,2,8,5)

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par skuatamad Voir le message
    Salut,
    A mon avis il faut utiliser une colonne fictive pour créer un ordre par nombre, unir les résultats et enfin les trier selon cet ordre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT TEXT, 1 as ordre FROM MYTAB WHERE NOMBRE = 2
    UNION ALL
    SELECT TEXT, 2 as ordre FROM MYTAB WHERE NOMBRE = 8
    UNION ALL
    SELECT TEXT, 3 as ordre FROM MYTAB WHERE NOMBRE = 5
    order by ordre
    Mais je ne sais pas si cette solution peut te convenir.
    Bon c'est peut être possible de créer la colonne ordre tout en évitant les UNION ALL, mais ça restera peu intuitif.
    Merci pour la suggestion, je vais essayer ca. Je ne connais pas UNION : est-ce que la solution que tu me proposes constitue une seule et unique requête?

    Mon problème est de limiter au maximum le nombre de requête SQL, car chaque requête est assez lente (acslXtreme, le logiciel que j'utilise a un support très rudimentaire & non optimisé de ces requêtes, et la base de données est sur un serveur).
    Si je n'avais pas ce problème de vitesse, la solution la plus simple serait de faire 2 requêtes : une pour récupérer NOMBRE, une pour récupérer TEXTE, puis d'utiliser le langage d'analyse d'acslXtreme pour retrouver les valeurs qui m'intéressent.
    D'où ma question pour faire ca directement en 1 étape dans la requête SQL...

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Cybher Voir le message
    salut,

    tu peux essayer ceci peut etre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    order by field(nombre,2,8,5)
    Je vais essayer ca aussi.
    Merci pour votre aide.

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Cybher Voir le message
    salut,

    tu peux essayer ceci peut etre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    order by field(nombre,2,8,5)
    Après lecture de qq pages web sur ORDER BY FIELD, il semblerait que ce soit la solution que je cherche.
    Mais je viens de me rendre compte en testant le code que la SGDB utilisée n'est pas Oracle, mais Access (mi stupido... ). En effet, les données sont bien stockées sous Oracle, mais une base Access "tampon" est utilisée en local, et acslXtreme lit une vue de la base Oracle stockée dans la base Access. [Désolé, je suis débutant en SQL, et je ne savais pas que le SQL était implémenté différemment entre les différentes SGDB (je pensais que c'était un standard)]

    J'obtiens l'erreur suivante en utilisant cette requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Error in function sqlQuery:
    	Code = 800a0c0d
    	Code meaning = Unknown error 0x800A0C0D
    	Source = DAO.Database
    	Description = Fonction 'FIELD' non définie dans l'expression.
    C'est Source = DAO.Database qui m'a fait me rappeler le fait que c'est la base Access qui est lue.
    Ma question suivante est donc: FIELD est-il utilisable sous Access? Si non, existe-t-il un equivalent?

  9. #9
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par sirfratus Voir le message
    est-ce que la solution que tu me proposes constitue une seule et unique requête?
    Oui c'est une seule requête mais évidemment le mode d'accès aux données est différent de celui d'un IN et sûrement moins performant. La requête proposée est plus une solution de contournement, qu'une vrai solution...

    Merci Cybher pour le ORDER BY FIELD, je ne connaissais pas, mais ça ne marche pas sur oracle non plus. Ca ressemble a une spécificité mysql, tu l'as déjà utilisé sur d'autres SGBDs?

  10. #10
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    Citation Envoyé par skuatamad Voir le message
    Merci Cybher pour le ORDER BY FIELD, je ne connaissais pas, mais ça ne marche pas sur oracle non plus. Ca ressemble a une spécificité mysql, tu l'as déjà utilisé sur d'autres SGBDs?
    c'est peut être effectivement spécifique à MySQL... mais je n'étais pas sur

  11. #11
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 284
    Points : 11 737
    Points
    11 737
    Par défaut
    Il ne s'agit pas de ORDER BY FIELD, mais simplement de la fonction FIELD() dans un ORDER BY. Et effectivement, cette fonction n'existe ni dans Access, ni dans Oracle.

    La solution de skuatamad est bonne, et techniquement parlant, c'est une seule requête. Par contre, je pense que les performances seront assez mauvaises (à tester).

    Une alternative sous Oracle serait le DECODE() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ORDER BY DECODE(nombre, 2, 1, 8, 2, 5, 3)
    Autrement dit, 2 => 1ère position, 8 => 2ème, 5 => 3ème.

    L'équivalent sous Access serait switch() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ORDER BY DECODE(nombre = 2, 1, nombre = 8, 2, nombre = 5, 3)
    Enfin, en syntaxe normalisée, il faudrait utiliser la structure CASE WHEN :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ORDER BY CASE nombre 
      WHEN 2 THEN 1
      WHEN 8 THEN 2
      WHEN 5 THEN 3
    END
    Oracle comprend, et peut-être les versions récentes d'Access aussi ?

  12. #12
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 950
    Points : 5 849
    Points
    5 849
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    SQL> select * from v$version;
     
    BANNER
    ----------------------------------------------------------------
    Oracle Database 10g Express Edition Release 10.2.0.1.0 - Product
    PL/SQL Release 10.2.0.1.0 - Production
    CORE    10.2.0.1.0      Production
    TNS for Linux: Version 10.2.0.1.0 - Production
    NLSRTL Version 10.2.0.1.0 - Production
     
    SQL> create table MYTAB (nombre int, text varchar2(5));
     
    Table cr��e.
     
    Ecoul� : 00 :00 :00.02
    SQL> begin
    for i in 1..100000 loop
            insert into mytab values (i,'XXXXX');
    end loop;
    commit;
    end;
    /  2    3    4    5    6    7  
     
    Proc�dure PL/SQL termin�e avec succ�s.
     
    Ecoul� : 00 :00 :03.17
    SQL> set autotrace traceonly explain
    SQL> select text from mytab where nombre in (2000,80000,50) order by nombre;
    Ecoul� : 00 :00 :00.01
     
    Plan d'ex�cution
    ----------------------------------------------------------
    Plan hash value: 1028169493
     
    ----------------------------------------------------------------------------
    | Id  | Operation          | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |       |     8 |   136 |    71   (5)| 00:00:01 |
    |   1 |  SORT ORDER BY     |       |     8 |   136 |    71   (5)| 00:00:01 |
    |*  2 |   TABLE ACCESS FULL| MYTAB |     8 |   136 |    70   (3)| 00:00:01 |
    ----------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       2 - filter("NOMBRE"=50 OR "NOMBRE"=2000 OR "NOMBRE"=80000)
     
    Note
    -----
       - dynamic sampling used for this statement
     
    SQL> SELECT TEXT, 1 AS ordre FROM MYTAB WHERE NOMBRE = 2000
    UNION ALL
    SELECT TEXT, 2 AS ordre FROM MYTAB WHERE NOMBRE = 80000
    UNION ALL
    SELECT TEXT, 3 AS ordre FROM MYTAB WHERE NOMBRE = 50
    ORDER BY ordre;  2    3    4    5    6  
    Ecoul� : 00 :00 :00.02
     
    Plan d'ex�cution
    ----------------------------------------------------------
    Plan hash value: 3851462616
     
    -----------------------------------------------------------------------------
    | Id  | Operation           | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
    -----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT    |       |    11 |   187 |   211   (4)| 00:00:03 |
    |   1 |  SORT ORDER BY      |       |    11 |   187 |   210  (68)| 00:00:03 |
    |   2 |   UNION-ALL         |       |       |       |            |          |
    |*  3 |    TABLE ACCESS FULL| MYTAB |     4 |    68 |    70   (3)| 00:00:01 |
    |*  4 |    TABLE ACCESS FULL| MYTAB |     4 |    68 |    70   (3)| 00:00:01 |
    |*  5 |    TABLE ACCESS FULL| MYTAB |     3 |    51 |    70   (3)| 00:00:01 |
    -----------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       3 - filter("NOMBRE"=2000)
       4 - filter("NOMBRE"=80000)
       5 - filter("NOMBRE"=50)
     
    Note
    -----
       - dynamic sampling used for this statement
     
    SQL> select text from mytab 
    where nombre in (2000,80000,50)
    ORDER BY CASE nombre 
      WHEN 2000 THEN 1
      WHEN 80000 THEN 2
      WHEN 50 THEN 3
    END;  2    3    4    5    6    7  
    Ecoul� : 00 :00 :00.01
     
    Plan d'ex�cution
    ----------------------------------------------------------
    Plan hash value: 1028169493
     
    ----------------------------------------------------------------------------
    | Id  | Operation          | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |       |     8 |   136 |    71   (5)| 00:00:01 |
    |   1 |  SORT ORDER BY     |       |     8 |   136 |    71   (5)| 00:00:01 |
    |*  2 |   TABLE ACCESS FULL| MYTAB |     8 |   136 |    70   (3)| 00:00:01 |
    ----------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       2 - filter("NOMBRE"=50 OR "NOMBRE"=2000 OR "NOMBRE"=80000)
     
    Note
    -----
       - dynamic sampling used for this statement
     
    SQL> create unique index idx_nb on mytab(nombre);
     
    Index cr�
     
    Ecoul� : 00 :00 :00.50
    SQL> select text from mytab where nombre in (2000,80000,50) order by nombre;
    Ecoul� : 00 :00 :00.01
     
    Plan d'ex�cution
    ----------------------------------------------------------
    Plan hash value: 3973717430
     
    ---------------------------------------------------------------------------------------
    | Id  | Operation                    | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT             |        |     8 |   136 |     5   (0)| 00:00:01 |
    |   1 |  INLIST ITERATOR             |        |       |       |            |          |
    |   2 |   TABLE ACCESS BY INDEX ROWID| MYTAB  |     8 |   136 |     5   (0)| 00:00:01 |
    |*  3 |    INDEX RANGE SCAN          | IDX_NB |   297 |       |     4   (0)| 00:00:01 |
    ---------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       3 - access("NOMBRE"=50 OR "NOMBRE"=2000 OR "NOMBRE"=80000)
           filter("NOMBRE"=50 OR "NOMBRE"=2000 OR "NOMBRE"=80000)
     
    Note
    -----
       - dynamic sampling used for this statement
     
    SQL> SELECT TEXT, 1 AS ordre FROM MYTAB WHERE NOMBRE = 2000
    UNION ALL
    SELECT TEXT, 2 AS ordre FROM MYTAB WHERE NOMBRE = 80000
    UNION ALL
    SELECT TEXT, 3 AS ordre FROM MYTAB WHERE NOMBRE = 50
    ORDER BY ordre;  2    3    4    5    6  
    Ecoul� : 00 :00 :00.01
     
    Plan d'ex�cution
    ----------------------------------------------------------
    Plan hash value: 2675980844
     
    ----------------------------------------------------------------------------------------
    | Id  | Operation                     | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT              |        |     3 |    51 |     4  (25)| 00:00:01 |
    |   1 |  SORT ORDER BY                |        |     3 |    51 |     3  (67)| 00:00:01 |
    |   2 |   UNION-ALL                   |        |       |       |            |          |
    |   3 |    TABLE ACCESS BY INDEX ROWID| MYTAB  |     1 |    17 |     1   (0)| 00:00:01 |
    |*  4 |     INDEX UNIQUE SCAN         | IDX_NB |     1 |       |     1   (0)| 00:00:01 |
    |   5 |    TABLE ACCESS BY INDEX ROWID| MYTAB  |     1 |    17 |     1   (0)| 00:00:01 |
    |*  6 |     INDEX UNIQUE SCAN         | IDX_NB |     1 |       |     1   (0)| 00:00:01 |
    |   7 |    TABLE ACCESS BY INDEX ROWID| MYTAB  |     1 |    17 |     1   (0)| 00:00:01 |
    |*  8 |     INDEX UNIQUE SCAN         | IDX_NB |     1 |       |     1   (0)| 00:00:01 |
    ----------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       4 - access("NOMBRE"=2000)
       6 - access("NOMBRE"=80000)
       8 - access("NOMBRE"=50)
     
    SQL> select text from mytab 
    where nombre in (2000,80000,50)
    ORDER BY CASE nombre 
      WHEN 2000 THEN 1
      WHEN 80000 THEN 2
      WHEN 50 THEN 3
    END;  2    3    4    5    6    7  
    Ecoul� : 00 :00 :00.01
     
    Plan d'ex�cution
    ----------------------------------------------------------
    Plan hash value: 2636313443
     
    ----------------------------------------------------------------------------------------
    | Id  | Operation                     | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT              |        |     8 |   136 |     6  (17)| 00:00:01 |
    |   1 |  SORT ORDER BY                |        |     8 |   136 |     6  (17)| 00:00:01 |
    |   2 |   INLIST ITERATOR             |        |       |       |            |          |
    |   3 |    TABLE ACCESS BY INDEX ROWID| MYTAB  |     8 |   136 |     5   (0)| 00:00:01 |
    |*  4 |     INDEX RANGE SCAN          | IDX_NB |   297 |       |     4   (0)| 00:00:01 |
    ----------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       4 - access("NOMBRE"=50 OR "NOMBRE"=2000 OR "NOMBRE"=80000)
     
    Note
    -----
       - dynamic sampling used for this statement
     
    SQL> drop index idx_nb;
     
    Index supprim
     
    Ecoul� : 00 :00 :00.20
    SQL> create index idx_nb on mytab(nombre);
     
    Index cr�
     
    Ecoul� : 00 :00 :00.32
    SQL> select text from mytab where nombre in (2000,80000,50) order by nombre;
    Ecoul� : 00 :00 :00.01
     
    Plan d'ex�cution
    ----------------------------------------------------------
    Plan hash value: 3973717430
     
    ---------------------------------------------------------------------------------------
    | Id  | Operation                    | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT             |        |     8 |   136 |     5   (0)| 00:00:01 |
    |   1 |  INLIST ITERATOR             |        |       |       |            |          |
    |   2 |   TABLE ACCESS BY INDEX ROWID| MYTAB  |     8 |   136 |     5   (0)| 00:00:01 |
    |*  3 |    INDEX RANGE SCAN          | IDX_NB |   297 |       |     4   (0)| 00:00:01 |
    ---------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       3 - access("NOMBRE"=50 OR "NOMBRE"=2000 OR "NOMBRE"=80000)
           filter("NOMBRE"=50 OR "NOMBRE"=2000 OR "NOMBRE"=80000)
     
    Note
    -----
       - dynamic sampling used for this statement
     
    SQL> SELECT TEXT, 1 AS ordre FROM MYTAB WHERE NOMBRE = 2000
    UNION ALL
    SELECT TEXT, 2 AS ordre FROM MYTAB WHERE NOMBRE = 80000
    UNION ALL
    SELECT TEXT, 3 AS ordre FROM MYTAB WHERE NOMBRE = 50
    ORDER BY ordre;  2    3    4    5    6  
    Ecoul� : 00 :00 :00.22
     
    Plan d'ex�cution
    ----------------------------------------------------------
    Plan hash value: 3379437080
     
    ----------------------------------------------------------------------------------------
    | Id  | Operation                     | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT              |        |     3 |    51 |     7  (15)| 00:00:01 |
    |   1 |  SORT ORDER BY                |        |     3 |    51 |     6  (67)| 00:00:01 |
    |   2 |   UNION-ALL                   |        |       |       |            |          |
    |   3 |    TABLE ACCESS BY INDEX ROWID| MYTAB  |     1 |    17 |     2   (0)| 00:00:01 |
    |*  4 |     INDEX RANGE SCAN          | IDX_NB |     1 |       |     1   (0)| 00:00:01 |
    |   5 |    TABLE ACCESS BY INDEX ROWID| MYTAB  |     1 |    17 |     2   (0)| 00:00:01 |
    |*  6 |     INDEX RANGE SCAN          | IDX_NB |     1 |       |     1   (0)| 00:00:01 |
    |   7 |    TABLE ACCESS BY INDEX ROWID| MYTAB  |     1 |    17 |     2   (0)| 00:00:01 |
    |*  8 |     INDEX RANGE SCAN          | IDX_NB |     1 |       |     1   (0)| 00:00:01 |
    ----------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       4 - access("NOMBRE"=2000)
       6 - access("NOMBRE"=80000)
       8 - access("NOMBRE"=50)
     
    Note
    -----
       - dynamic sampling used for this statement
     
    SQL> select text from mytab 
    where nombre in (2000,80000,50)
    ORDER BY CASE nombre 
      WHEN 2000 THEN 1
      WHEN 80000 THEN 2
      WHEN 50 THEN 3
    END;  2    3    4    5    6    7  
    Ecoul� : 00 :00 :00.01
     
    Plan d'ex�cution
    ----------------------------------------------------------
    Plan hash value: 2636313443
     
    ----------------------------------------------------------------------------------------
    | Id  | Operation                     | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT              |        |     8 |   136 |     6  (17)| 00:00:01 |
    |   1 |  SORT ORDER BY                |        |     8 |   136 |     6  (17)| 00:00:01 |
    |   2 |   INLIST ITERATOR             |        |       |       |            |          |
    |   3 |    TABLE ACCESS BY INDEX ROWID| MYTAB  |     8 |   136 |     5   (0)| 00:00:01 |
    |*  4 |     INDEX RANGE SCAN          | IDX_NB |   297 |       |     4   (0)| 00:00:01 |
    ----------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):
    ---------------------------------------------------
     
       4 - access("NOMBRE"=50 OR "NOMBRE"=2000 OR "NOMBRE"=80000)
     
    Note
    -----
       - dynamic sampling used for this statement
     
    SQL>
    Bon la différence de perf (dans ce test un peu vite fait) me semble pas dramatique (à voir dans des conditions réelles évidemment), même si sans index le cost du UNION ALL est plus nettement supérieur.
    En tout cas, autant l'utilisation d'un CASE dans un SELECT est un réflexe, déjà dans un WHERE faut que je me force, mais dans un ORDER BY ben j'y avais jamais pensé, donc merci Antoun pour l'astuce

  13. #13
    Rédacteur/Modérateur

    Avatar de Antoun
    Homme Profil pro
    Architecte décisionnel
    Inscrit en
    Octobre 2006
    Messages
    6 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Architecte décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2006
    Messages : 6 284
    Points : 11 737
    Points
    11 737
    Par défaut
    you welcome !

    Par ailleurs, je n'ai jamais dit que le CASE (ni le DECODE / switch) serait particulièrement performant

  14. #14
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 9
    Points : 2
    Points
    2
    Par défaut
    En tout cas, merci à tous pour vos suggestions, je vais tester les différentes solutions pour voir celles qui marchent le mieux.

Discussions similaires

  1. Probléme tri des donnée de sortie
    Par jeannotmer dans le forum 4D
    Réponses: 10
    Dernier message: 12/07/2007, 15h57
  2. [IN] - Tri des données
    Par kirsoul dans le forum Langage SQL
    Réponses: 1
    Dernier message: 02/05/2006, 15h36
  3. tri des données différent entre 2 bases
    Par j6m dans le forum Oracle
    Réponses: 2
    Dernier message: 12/03/2006, 10h17
  4. [Access] Enregistrer des données de type Texte RTF
    Par portu dans le forum Bases de données
    Réponses: 22
    Dernier message: 27/10/2005, 22h54
  5. [JTable] Tri des données
    Par soulhouf dans le forum Composants
    Réponses: 7
    Dernier message: 08/09/2005, 14h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo