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

Requêtes MySQL Discussion :

Sélectionner plusieurs fois une ligne


Sujet :

Requêtes MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2014
    Messages
    266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2014
    Messages : 266
    Par défaut Sélectionner plusieurs fois une ligne
    Bonjour,
    Existe t il une requête simple permettant d'obtenir ce résultat là ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT id FROM table WHERE id IN(1,2,3,1,1,2)
    Résultat :
    1
    2
    3
    1
    1
    2
    Car cette requête donne dans la pratique :
    1
    2
    3

  2. #2
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 706
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 706
    Billets dans le blog
    10
    Par défaut
    si vous ne voulez récupérer que les Id, inutile de mettre une table et un filtre where, car votre requête revient à

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select '1', '2', '3', '1', '1', '2'


    Sinon, faute de 'DISTINCT' vous devez bien avoir autant de lignes restituées que de lignes dans la table correspondant au filtre where
    êtes vous certains que votre table contient trois fois la valeur d'id 1 comme dans votre exemple ?

  3. #3
    Membre chevronné Avatar de Sebwar
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Avril 2012
    Messages
    172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2012
    Messages : 172
    Par défaut
    Hello !

    Est ce qu'on pourrait avoir plus d'infos sur le contexte pour t'orienter vers la meilleure solution ?

    sinon tu peux faire 3 requêtes, mais je ne pense pas que ce soit la meilleure solution
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT id FROM table WHERE id in (1, 2, 3) order by id
    SELECT id FROM table WHERE id = 1
    SELECT id FROM table WHERE in (1, 2) order by id

  4. #4
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Bonjour,

    Vous pouvez faire comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    SELECT id
    FROM (
    	SELECT 1 as id
    	union all select 2
    	union all select 3
    	union all select 1
    	union all select 1
    	union all select 2
     
    ) AS T
    INNER JOIN LaTable	
    	ON LaTable.a = T.id
    Quel est le but de tout ça ? et d'où provient votre liste de valeurs ?

  5. #5
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2014
    Messages
    266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2014
    Messages : 266
    Par défaut
    Merci pour toutes vos propositions.
    Celles ci fonctionnement certainement mais ne sont sûrement pas utilisables avec des variables. et je souhaite éviter les boucles car cela me semble démesuré pour ce type de requête. Je précise un peu ce que je souhaite faire :
    En fait cette requête doit permettre par exemple à partir d'une liste de numéro non connue à l'avance
    @liste_des_id_par_ordre_chronologique
    de récupérer les informations et ce de manière chronologique et par la suite les afficher dans l'ordre d'apparition sans se soucier du nombre de répétitions d'id, par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT id, nom FROM table WHERE id IN(@liste_des_id_par_ordre_chronologique)  ORDER BY FIELD (@liste_des_id_par_ordre_chronologique)
    Ce code ne peut pas marcher puisque si @liste_des_id_par_ordre_chronologique contient deux id identiques la requête ne va en sélectionner qu'une seule ligne alors que je souhaite avoir 2 fois la même ligne dans le résultat.

  6. #6
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2014
    Messages
    266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2014
    Messages : 266
    Par défaut
    En conclusion : MYSQL ne permet pas de faire une selection multiple de lignes identiques avec une seule ligne de requête sans passer par une deuxième table + INNER JOIN.
    La solution décrite par Artemus24 est la seule méthode en MYSQL pur.

    J'ai préféré finalement une variante en PHP/MYSQL en s'inspirant de ceci :
    Citation Envoyé par aieeeuuuuu Voir le message
    Bonjour,

    Vous pouvez faire comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    SELECT id
    FROM (
    	SELECT 1 as id
    	union all select 2
    	union all select 3
    	union all select 1
    	union all select 1
    	union all select 2
     
    ) AS T
    INNER JOIN LaTable	
    	ON LaTable.a = T.id
    Quel est le but de tout ça ? et d'où provient votre liste de valeurs ?
    Au final le code php ressemble à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $liste_id="'1','2','3','1','1','2'";
    $list_id_tab=explode(",",$liste_id);
    $sqltmp="SELECT id FROM (SELECT ".implode(" as ID UNION ALL SELECT ",$list_id_tab)." as ID ) as T INNER JOIN TABLE_SOURCE ON T.ID=TABLE_SOURCE.".id";
    mysqli_query($base,$sqltmp) or die('Erreur SQL !<br /><br />'.mysqli_error($base));
    Résultat :
    1
    2
    3
    1
    1
    2
    Merci à tous.

  7. #7
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    7 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 7 243
    Par défaut
    Salut à tous.

    Voilà une question intéressante, même si sa porté est fort limitée.
    Je crois me souvenir que cette question a déjà été posée !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT id FROM table WHERE id IN(1,2,3,1,1,2)
    Il n'est pas possible, avec une simple requête, d'ordonner le tri dans un ordre bien précis et aussi de produire une répétition des tuples.

    La seule solution pour obtenir ce genre de résultat est de créer une table qui va faire l'ordonnancement.
    Autrement dit, il y a correspondance entre une table qui ordonne et l'autre qui va subir l'ordonnancement.
    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
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE `base`
            DEFAULT CHARACTER SET `latin1`
            DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `lien`
    --------------
     
    --------------
    CREATE TABLE `lien`
    ( `num`  integer unsigned  NOT NULL auto_increment primary key,
      `pos`  integer unsigned  NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    INSERT INTO `lien` (`pos`) VALUES (1),(2),(3),(1),(1),(2)
    --------------
     
    --------------
    select * from lien
    --------------
     
    +-----+-----+
    | num | pos |
    +-----+-----+
    |   1 |   1 |
    |   2 |   2 |
    |   3 |   3 |
    |   4 |   1 |
    |   5 |   1 |
    |   6 |   2 |
    +-----+-----+
    --------------
    DROP TABLE IF EXISTS `test`
    --------------
     
    --------------
    CREATE TABLE `test`
    ( `id`    integer unsigned  NOT NULL primary key,
      `nom`   char(10)          NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    INSERT INTO `test` (`id`,`nom`) VALUES (1,'un'),(2,'deux'),(3,'trois')
    --------------
     
    --------------
    select * from test
    --------------
     
    +----+-------+
    | id | nom   |
    +----+-------+
    |  1 | un    |
    |  2 | deux  |
    |  3 | trois |
    +----+-------+
    --------------
    select t.nom
    from       lien as l
     
    inner join test as t
    on t.id = l.pos
     
    order by l.num
    --------------
     
    +-------+
    | nom   |
    +-------+
    | un    |
    | deux  |
    | trois |
    | un    |
    | un    |
    | deux  |
    +-------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
     
    Appuyez sur une touche pour continuer...
    Inversement voici comment trier selon un ordre particulier :
    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
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE `base`
            DEFAULT CHARACTER SET `latin1`
            DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `test`
    --------------
     
    --------------
    CREATE TABLE `test`
    ( `id`    integer unsigned  NOT NULL auto_increment primary key,
      `jour`  varchar(255)      NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    INSERT INTO `test` (`jour`) VALUES ('lundi'),('mardi'),('mercredi'),('jeudi'),('vendredi'),('samedi'),('dimanche')
    --------------
     
    --------------
    select * from test order by id
    --------------
     
    +----+----------+
    | id | jour     |
    +----+----------+
    |  1 | lundi    |
    |  2 | mardi    |
    |  3 | mercredi |
    |  4 | jeudi    |
    |  5 | vendredi |
    |  6 | samedi   |
    |  7 | dimanche |
    +----+----------+
    --------------
    select * from test order by jour
    --------------
     
    +----+----------+
    | id | jour     |
    +----+----------+
    |  7 | dimanche |
    |  4 | jeudi    |
    |  1 | lundi    |
    |  2 | mardi    |
    |  3 | mercredi |
    |  6 | samedi   |
    |  5 | vendredi |
    +----+----------+
    --------------
    select * from test order by field(id, 4, 6, 1, 3, 5, 7, 2)
    --------------
     
    +----+----------+
    | id | jour     |
    +----+----------+
    |  4 | jeudi    |
    |  6 | samedi   |
    |  1 | lundi    |
    |  3 | mercredi |
    |  5 | vendredi |
    |  7 | dimanche |
    |  2 | mardi    |
    +----+----------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
     
    Appuyez sur une touche pour continuer...
    @+

  8. #8
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2014
    Messages
    266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2014
    Messages : 266
    Par défaut
    Heu.. oui c'est pas une solution si simple que cela, je me demande si une boucle serait pas plus rapide.
    Il n'existe pas de fonction qui pourrait être comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT REPEAT(SELECT id,5) FROM table WHERE id=1
    permettant d'obtenir :
    1
    1
    1
    1
    1
    et non :
    11111

  9. #9
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    7 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 7 243
    Par défaut
    Salut xounet.

    La notion de boucle n'existe pas !
    La seule façon de faire ce que tu veux entreprendre est de le gérer en php.

    @+

  10. #10
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2014
    Messages
    266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2014
    Messages : 266
    Par défaut
    Oui c'est une solution mais en php ! (ce qui est pas si mal d'ailleurs)
    Mais tu as l'air vraiment affirmatif donc...
    J'ai plusieurs autres pistes quand même :
    -solutionner le problème à la base c'est à dire utiliser un système d'id chronologique et non numérique pur , avec des lignes en doubles dans la table, comme cela il n'y a que des id uniques dans la variables @liste_id_ordre_chronologique mais la table "table" va grossir inutilement ...

    -Peut être en utilisant CROSS JOIN en adaptant si nécessaire @liste_id pour s'apparenter à une table ? à creuser je pense (si quelqu'un peut m'éclairer là dessus...), j'ai trouvé ce site qui en montre un exemple assez simple qui pourrait s'adapter :
    http://www.w3resource.com/mysql/adva...cross-join.php

    -éventuellement trouver une solution qui permettrait de faire une datation dans la requête en elle même du genre et revenir à la première sélection au temps (t-n) si celle-ci se répète...bref d'un niveau supérieur...

    Qu'en pensez vous ?

  11. #11
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    7 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 7 243
    Par défaut
    Salut xounet.

    Voici un exemple en php :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $sel = $link->prepare("SELECT id, nom from test");
    $sel->execute();
     
    $row = $sel->fetchall(PDO::FETCH_COLUMN|PDO::FETCH_GROUP);
     
    print_r ($row);
     
    foreach(array(1, 2, 3, 1, 1, 2) as $pos)
    	echo $row[$pos][0]."\n";
    C'est la même table test que dans mon précédent message (post #6).
    Et voici le résultat à l'affichage :
    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
    Array
    (
        [1] => Array
            (
                [0] => un
            )
     
        [2] => Array
            (
                [0] => deux
            )
     
        [3] => Array
            (
                [0] => trois
            )
     
    )
    un
    deux
    trois
    un
    un
    deux
    Tu poses mal ton problème.
    Pour approfondir la question, il faudrait que cela soit sur un cas réel.

    @+

  12. #12
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2014
    Messages
    266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2014
    Messages : 266
    Par défaut
    Merci beaucoup pour ta proposition de code qui est intéressante il est moins lourd de recopier en mémoire vive les lignes pour affiche avec echo que dans une table, mais je ne désespère pas (encore) de trouver un solution avec un peu moins de lignes de code mysql que ta version php !
    Mais tu as sûrement raison, car la requête MYSQL par nature s'exécute dans un ordre chronologique et un ordre logique, évitant certainement les requêtes en boucle infinies... (autre sujet), il n'y a peut être pas d'autre solution et ce type de code est à éviter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SET @x=1;
    SELECT @x,@x:=@x+1, id,concat(@x,id) FROM table WHERE id IN(20,5,@x-10,1)
    ce code n'affiche pas plus de lignes celles des id :
    1
    5
    20

    L'application de ce code n'apportera pas plus de compréhension ou de solutions... ceci aurait permis entre autre d'afficher du texte repéré par un numero id qui se répète selon une certaine séquence...

    Concernant le CROSS JOIN pensez vous qu'il y a une éventuelle possibilité ?

  13. #13
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    7 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 7 243
    Par défaut
    Salut xounet.

    Comme je l'ai dit, la notion de boucle n'existe pas dans la gestion des bases de données.
    Il ne faut pas oublier que la théorie sous-jacente est la théorie des ensembles.

    Il n'y a pas de notions de tableaux en mysql.

    Je pense que le sujet n'est pas terminé car il existe une autre approche, celle des procédures stockées.
    J'aimerai savoir ce que représente cette suite de nombres : "1, 2, 3, 1, 1, 2" dans ton exemple ?
    Et comment vas-tu gérer cela en MySql ?

    @+

  14. #14
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    il serait surtout utile de connaitre le but de tout ça.

    Car si c'est au final pour n'afficher que les id présents dans la table, autant de fois qu'ils sont dans la liste (et eventuellement dans le même ordre), alors il est bien plus simple de rester sur la première requete (pour connaitre les id existants), et de faire le rapprochement ensuite entre le résultat de la requete et la liste initiale en php pour l'affichage.

  15. #15
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2014
    Messages
    266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2014
    Messages : 266
    Par défaut
    Re bonjour,

    J'ai rapidement expliqué l'application de cette requête, elle est tellement basique qu'il est difficile de vous en donner plus de détails, le but de ma question n'est pas non plus de revoir toute la conception de mon programme, ce n'est pas pour cela que je poste des questions sur le forum, donc allons à l'essentiel d'autant plus qu'il est plus facile pour les autres utilisateurs confrontés à cette problématique de réutiliser un programme "générique" plutôt qu'un programme "spécifique" en tous les cas c'est ce que je pense.

    Voici exactement ce que doit pouvoir faire la requête MYSQL :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    table 1
     
    id	texte
    1	texte1
    2	texte2
    3	texte3
    4	texte4
    5	texte5
    6	texte6
    Au cours de l'exécution du programme, l'utilisateur choisit une série d'id dont la taille et le contenu ne peuvent être connus à l'avance (forcément) on obtient en retour la liste :
    exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $liste_id="'1','2','3','1','1','2'";
    et le programme doit se charger d'afficher le texte correspondant à cette séquence d' id. Ici je souhaite obtenir tout simplement le résultat :
    texte1
    texte2
    texte3
    texte1
    texte1
    texte2
    cas général :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $liste_id="'n1','n2',.......(z valeurs).................,'nn'";
    et la requête mysql doit permettre de sélection tous les champs texte qui ont les id indiqués dans la liste $liste_id :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    $list_id_tab=explode(',',$liste_id);
    $sqltmp="SELECT texe,autre_champ FROM (SELECT ".implode(" as ID UNION ALL SELECT ",$list_id_tab)." as ID ) as T INNER JOIN TABLE_SOURCE ON T.ID=TABLE_SOURCE.".id";
    $reqtmp = mysqli_query($base,$sqltmp) or die('Erreur SQL !<br /><br />'.mysqli_error($base));
    while ($datatmp = mysqli_fetch_array($reqtmp)) {
     
    ..........
     
    echo $datatmp['texte']."\n\r";
    ........
     
    }
    pour afficher :

    texte_n1
    texte_n2
    ----
    z valeurs
    ----
    texte_nn
    Je souhaitais à la base faire une seule requête MYSQL pour une exécution rapide, mais comme cela n'est pas possible j'ai inséré le script php permettant de construite une requête MYSQL plus complexe. En fait je pensais vraiment à l'origine qu'il y avait une méthode directe et simple pour obtenir ce résultat en faisant quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT ALL/UNION/REPEAT texte FROM table 1 WHERE id IN(".$liste_id.") ORDER BY FIELD(id,".$liste_id.")
    mais en regardant de plus près ça ne pouvait pas marcher.
    Biensûr en utilisant php, il existe des dizaines de façon d'obtenir le résultat voulu.

    Après toutes ces explications je ne vois pas en quoi cela change le problème de fond...

    Concernant les procédures stockées j'avoue ne pas les utiliser car j'en ai jamais eu besoin et comme j'utilise déjà php, utiliser des algorithmes en MYSQL me paraît un peu de trop mais bon pourquoi pas ?

  16. #16
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Citation Envoyé par xounet Voir le message
    et le programme doit se charger d'afficher le texte correspondant
    Vous avez vu juste ! c'est bien au programme de se charger d'afficher plusieurs fois la même ligne s'il y a lieu. Le SGBDR ayant uniquement la charge de fournir les données.

    Il est quand même contre productif de créer une requete SQL inutilement compliquée (qui plus est dynamique, rendant surement impossible la réutilisation des plans d’exécution), tout ça pour obtenir les mêmes données en double, en triple en quadruple...
    Cette solution complexifie la maintenance (de la requete notamment), nuit aux performances (avec une requete plus compliquée, et des données inutiles transitant sur le réseau).

    Bref, récupérez vos données de façon unique (comme le fait votre requete initiale) et laissez à php le soin d'afficher dans l'ordre voulu, et autant de fois que voulu les données récupérées. (il suffit d'une simple boucle en php sur le tableau d'id initial, en allant chercher le contenu a afficher dans le résultat de la requete, vraiment rien de compliqué).

  17. #17
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2014
    Messages
    266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2014
    Messages : 266
    Par défaut
    Bonjour,

    En ce qui me concerne la solution que j'ai mise au point en créant une requête (voir mon précédent post) qui permet de sélectionner plusieurs fois la même ligne tout cela grâce à php et la commande "INNER JOIN" me convient parfaitement pour le moment, je pense d'ailleurs qu'en terme de rapidité, contrairement à ce que vous sous entendez, cet algorithme est la meilleure façon de produire ce résultat (mémoire+rapidité).
    L'éventuel défaut de de ma solution, serait d'avoir une liste d'id qui se rallonge à plusieurs milliers d'id (je prévois pour l'instant 500 id au max), la requête utilisant INNER JOIN sera donc très longue 10 à 15 fois plus qu'un simple SELECT id FROM table WHERE IN(....). A ce moment je pense que la seule solution qui permette de gérer tous les cas de figures sera du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    foreach($liste_id_tab as $id {
    $SQL="SELECT id,texte from table WHERE id=".$id.";
    $reqtmp = mysqli_query($base,$SQL) or die('Erreur SQL !<br /><br />'.mysqli_error($base));
    while ($datatmp = mysqli_fetch_array($reqtmp)) {
     
    ..........
     
    echo $datatmp['texte']."\n\r";
    ........
     
    }
    }

  18. #18
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    7 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 7 243
    Par défaut
    Salut xounet.

    Nous n'avons pas une vue d'ensemble de ce que tu veux faire, et donc, il est difficile de trouver une solution adapté à ton problème.

    Tu donnes cette liste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $liste_id="'1','2','3','1','1','2'";
    Et comme explication, tu nous dis :
    Citation Envoyé par xounet
    l'utilisateur choisit une série d'id dont la taille et le contenu ne peuvent être connus à l'avance (forcément)
    Pour moi, c'est pas suffisant. Voici quelques questions :

    1) combien d'occurrences au maximum, as-tu dans cette liste ?
    Est-ce au maximum 6 ? Ou bien est-ce un nombre variable ?
    Et si OUI pourquoi est-ce variable ?

    2) je t'ai proposé une solution à partir d'une table de nom "lien".
    Qu'est-ce qui t'empêche de stocker cette liste dans une table temporaire ?
    Pour la table, tu peux mettre autant d'occurrences que tu désires.

    3) comme je l'ai dit, mais tu n'as pas réagit : "les boucles n'existent pas dans les SGBD".
    Si tu veux produire une liste de six lignes, il te faut au préalable ces six lignes.
    Comment vas-tu obtenir ces six lignes ? Et ou vas-tu les stocker ?

    4) la solution que j'ai proposé est de faire une jointure entre ta table existante et celle où tu vas mettre la liste des "id".
    Elle est facile à mettre en oeuvre et ne pose aucun problème.

    Citation Envoyé par xounet
    Je souhaitais à la base faire une seule requête MYSQL pour une exécution rapide, mais comme cela n'est pas possible
    Non. Mais dans le contexte que tu donnes, en effet, ce n'est pas possible. Pourquoi ?
    Tu as une seule table contenant disons trois lignes. Et tu veux produire disons six lignes, à partir de cette table.
    A partir d'une seule table, il est impossible de produire six lignes. Pourquoi ?
    Le traitement de lecture de la table se fait de la première ligne jusqu'à la dernière, sans possibilité de revenir en arrière.
    Si tu as trois lignes, tu auras que trois occurrences mais pas six !

    5) la solution php a le mérite de répondre à ton besoin, sans créer une nouvelle table contenant la liste des "id".
    Mais elle a l'inconvénient d'être limité en volumétrie de ce que tu veux faire.
    Mais si tu gères disons dix lignes au maximum, cela ne va poser aucun problème.

    6) une autre solution est de faire une procédure stockée.
    Ce qui est dommage avec MySql, c'est que l'on ne peut pas faire un "select" à partir d'une procédure stockée au lieu d'une table, comme cela se fait actuellement.
    Si la liste est limité en nombre, on peut produire un résultat, comme tu l'attends.
    Et ou vas-tu ranger ce résultat ? Dans une table ? A l'affichage en php ?

    @+

  19. #19
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    7 243
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 7 243
    Par défaut
    Salut xounet.

    Tu n'as pas répondu à mes questions !

    Ce que tu proposes est une solution non performante.

    Et je n'ai toujours pas compris n'utilité de tout ça.

    @+

  20. #20
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2014
    Messages
    266
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2014
    Messages : 266
    Par défaut
    Faudrait faire un test pour évaluer la performance. Mais je pense en tous les cas que la dernière solution (poste précédent) que j'ai proposée peut fonctionner dans tous les cas même si $liste_id contient des milliers , dizaines de milliers de N° id.
    Après si tu as la solution permettant de faire mieux que les deux solutions que j'ai décrites précédemment sans aucune limite concernant $liste_id et en plus performant, cela peut intéresser certainement du monde. Je doute que créer des tables à la volées soit plus performant, et en plus ce sera plus gourmand au niveau mémoire dure+mémoire vive logiquement.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [AC-2007] Ouvrir une mdb plusieurs fois en ligne de commande
    Par libuma dans le forum Access
    Réponses: 8
    Dernier message: 15/02/2011, 11h35
  2. [RegEx] Détection d'une chaine présente plusieurs fois par ligne
    Par Tchupacabra dans le forum Langage
    Réponses: 6
    Dernier message: 03/07/2009, 17h54
  3. [MDX/SQL]Selectionner plusieurs fois une meme ligne
    Par Reskibil dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 07/02/2008, 16h51
  4. Réponses: 5
    Dernier message: 05/01/2006, 19h43
  5. Réponses: 4
    Dernier message: 02/09/2004, 22h43

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