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 :

Requête et sous requêtes [MySQL-5.7]


Sujet :

Requêtes MySQL

  1. #1
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2021
    Messages
    164
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Services de proximité

    Informations forums :
    Inscription : Décembre 2021
    Messages : 164
    Points : 187
    Points
    187
    Par défaut Requête et sous requêtes
    Bonsoir,

    Je suis venu poster sur le forum plus par curiosité que par nécessité, car ma requête fonctionne correctement, même plutôt bien pour les données que j'ai à extraire, mais j'aimerais savoir si il n'y a pas de méthode plus "simple" ou moins barbare d'extraire les données.

    Alors voilà, j'ai trois tables qui sont liées, une qui contient une liste de ville, une autre qui contient l'historique des villes par jour, et une qui contient toutes les actions faites sur un formulaire.

    Je pensais pouvoir faire, en plus des jointures, un simple GROUP BY, le problème est que je n'obtiens pas les résultats vides, d'ailleurs je m'excuse par avance, il y a un peu de PHP autours de ma requête :

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $requete = 'SELECT DISTINCT';
    foreach($dbh->query('select ville from matable where date_prod = date(NOW())  order by ville') as $row){
    			$requete = $requete.' 
     
                                           (SELECT COUNT(*)FROM t1 LEFT OUTER JOIN t2 ON t1.index = t2.id WHERE t2.nom = "Valeur 1" AND 
                                           DATE(t1.date)= date(NOW())) as valA'.(string)$index.', 
     
    				       (SELECT COUNT(*)FROM t1 LEFT OUTER JOIN t2 ON t1.index = t2.id WHERE t2.nom = "Valeur 2" AND 
                                           DATE(t1.date)= date(NOW())) as valB'.(string)$index.',
     
    				      $index ++;

    En supposant que dans mon historique j'ai 2 villes, la rendu de la requête serait ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT DISTINCT
                                            (SELECT COUNT(*)FROM t1 LEFT OUTER JOIN t2 ON t1.index = t2.id WHERE ville ="MARSEILLE" AND t2.nom = "Valeur 1" AND 
                                           DATE(t1.date)= date(NOW())) as valA1, 
     
    				       (SELECT COUNT(*)FROM t1 LEFT OUTER JOIN t2 ON t1.index = t2.id WHERE ville ="MARSEILLE" AND  t2.nom = "Valeur 2" AND 
                                           DATE(t1.date)= date(NOW())) as valB1,
     
                                           (SELECT COUNT(*)FROM t1 LEFT OUTER JOIN t2 ON t1.index = t2.id WHERE ville ="PARIS" AND t2.nom = "Valeur 1" AND 
                                           DATE(t1.date)= date(NOW())) as valA2, 
     
    				       (SELECT COUNT(*)FROM t1 LEFT OUTER JOIN t2 ON t1.index = t2.id WHERE ville ="PARIS" AND  t2.nom = "Valeur 2" AND 
                                           DATE(t1.date)= date(NOW())) as valB2
                                           FROM MATABLE
    Au départ, je faisais une requête par ville, autant dire qu'avec cette méthode je suis passé de 30/40 requêtes à une seule, donc le temps d'exécution est plus que correct, mais quand même, je suis sûr qu'il y a une façon de faire qui pourrait m'éviter cette requête créer dynamiquement

  2. #2
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    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 : 6 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Salut PrtitBoutDeCode.

    Code mysql : 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
    --------------
    START TRANSACTION
    --------------
     
    --------------
    set session collation_connection = "latin1_general_ci"
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE IF NOT EXISTS `base`
            DEFAULT CHARACTER SET `latin1`
            DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `ville`
    --------------
     
    --------------
    CREATE TABLE `ville`
    (  `id`    integer unsigned NOT NULL auto_increment primary key,
       `nom`   varchar(255)     NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    insert into `ville` (`nom`) values
      ('Toulouse'),('Bordeaux'),('Paris'),('Marseille')
    --------------
     
    --------------
    select * from `ville`
    --------------
     
    +----+-----------+
    | id | nom       |
    +----+-----------+
    |  1 | Toulouse  |
    |  2 | Bordeaux  |
    |  3 | Paris     |
    |  4 | Marseille |
    +----+-----------+
    --------------
    DROP TABLE IF EXISTS `historique`
    --------------
     
    --------------
    CREATE TABLE `historique`
    (  `id`    integer unsigned NOT NULL auto_increment primary key,
       `lib`   varchar(255)     NOT NULL,
       `date`  date             NOT NULL,
       `clef`  integer unsigned NOT NULL,
       CONSTRAINT `FK_01` FOREIGN KEY (`clef`) REFERENCES `ville` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    INSERT INTO `historique` (`lib`,`date`,`clef`) VALUES
      ('Valeur 1', '2022-01-05', 1),  ('Valeur 1', '2022-01-27', 2),
      ('Valeur 2', '2022-01-15', 2),  ('Valeur 1', '2022-02-01', 3),
      ('Valeur 2', '2022-02-17', 3),  ('Valeur 1', '2022-03-05', 3),
      ('Valeur 1', '2022-01-25', 4),  ('Valeur 2', '2022-04-01', 4),
      ('Valeur 1', '2022-03-11', 4),  ('Valeur 2', '2022-02-22', 4)
    --------------
     
    --------------
    SELECT * FROM `historique`
    --------------
     
    +----+----------+------------+------+
    | id | lib      | date       | clef |
    +----+----------+------------+------+
    |  1 | Valeur 1 | 2022-01-05 |    1 |
    |  2 | Valeur 1 | 2022-01-27 |    2 |
    |  3 | Valeur 2 | 2022-01-15 |    2 |
    |  4 | Valeur 1 | 2022-02-01 |    3 |
    |  5 | Valeur 2 | 2022-02-17 |    3 |
    |  6 | Valeur 1 | 2022-03-05 |    3 |
    |  7 | Valeur 1 | 2022-01-25 |    4 |
    |  8 | Valeur 2 | 2022-04-01 |    4 |
    |  9 | Valeur 1 | 2022-03-11 |    4 |
    | 10 | Valeur 2 | 2022-02-22 |    4 |
    +----+----------+------------+------+
    --------------
    select          t1.nom as Ville,
                    t2.lib as Détail,
                    count(*) as Nbre
               from `ville` as t1
    left outer join `historique` as t2
                 on  t2.clef=t1.id
     
              where t1.nom in ('Marseille','Paris')
                and t2.lib in ('Valeur 1','Valeur 2')
           group by t1.nom, t2.lib
    --------------
     
    +-----------+----------+------+
    | Ville     | Détail   | Nbre |
    +-----------+----------+------+
    | Paris     | Valeur 1 |    2 |
    | Paris     | Valeur 2 |    1 |
    | Marseille | Valeur 1 |    2 |
    | Marseille | Valeur 2 |    2 |
    +-----------+----------+------+
    --------------
    COMMIT
    --------------
     
    Appuyez sur une touche pour continuer...
    Il n'est pas nécessaire de procéder comme tu le fais.
    Une seule requête qui va recevoir la liste de tes villes et la liste de tes valeurs à tester.

    Le résultat sera un regroupent par ville et par valeur, dont on comptabilisera le nombre de résultats trouvés.

    Cordialement.
    Artemus24.
    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  3. #3
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2021
    Messages
    164
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Services de proximité

    Informations forums :
    Inscription : Décembre 2021
    Messages : 164
    Points : 187
    Points
    187
    Par défaut
    Bonjour,

    Et merci pour la réponse rapide, je pense que j'aurais du donner plus d'éléments des le premiers message.

    Effectivement ta réponse fonctionne, sauf que (et c'est de ma faute de ne pas avoir été clair ) admettons que j'ai la ville de paris dans mon historique mais qu'il n'y a rien eu de la journée,

    mon résultat devrait ressembler à ça :
    Nom : Capture d’écran 2022-04-08 155412.png
Affichages : 166
Taille : 2,5 Ko

    J'ai fait le test en ajoutant une ville 'test' et en la mettant dans la partie Ce que je n'arrive pas à faire c'est trouver une ville qui est dans mon historique sans mouvement dans la journée

    Il faudrait que ça donne quelque chose comme (select distinct ville, count(valeur 1),count(valeur 2),count(valeur 3)...)

    Mais en fin de compte je pense que la requête ne peut pas vraiment être plus rapide que maintenant, elle met environ 1s/1,5s à s'exécuter sur une base distante c'st plus que raisonnable

  4. #4
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    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 : 6 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Salut PetitBoutDeCode.

    Citation Envoyé par PetitBoutDeCode
    je pense que j'aurais du donner plus d'éléments des le premiers message.
    Comme par exemple, le descriptif de ta base, un jeu d'essai et le résultat attendu.
    Oui, cela aurait été plus simple à comprendre ta demande.

    Citation Envoyé par PetitBoutDeCode
    mon résultat devrait ressembler à ça :
    Cela depend par quel bout tu prends ta requête.
    J'ai ajouté la ville de "Lyon", sans l'historique.
    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
    --------------
    select          t1.nom as Ville,
                    t2.lib as Détail,
                    count(t2.id) as Nbre
               from `ville` as t1
    left outer join `historique` as t2
                 on  t2.clef=t1.id
     
              where  t1.nom in ('Marseille','Paris','Lyon')
                and (t2.lib in ('Valeur 1','Valeur 2')
                 or  t2.lib is NULL)
           group by t1.nom, t2.lib
    --------------
     
    +-----------+----------+------+
    | Ville     | Détail   | Nbre |
    +-----------+----------+------+
    | Paris     | Valeur 1 |    2 |
    | Paris     | Valeur 2 |    1 |
    | Marseille | Valeur 1 |    2 |
    | Marseille | Valeur 2 |    2 |
    | Lyon      | NULL     |    0 |
    +-----------+----------+------+
    --------------
    select          t2.nom as Ville,
                    t1.lib as Détail,
                    count(t2.id) as Nbre
               from `historique` as t1
    left outer join `ville` as t2
                 on  t2.id=t1.clef
     
              where  t2.nom in ('Marseille','Paris','Lyon')
                and (t1.lib in ('Valeur 1','Valeur 2')
                 or  t1.lib is NULL)
           group by t2.nom, t1.lib
    --------------
     
    +-----------+----------+------+
    | Ville     | Détail   | Nbre |
    +-----------+----------+------+
    | Paris     | Valeur 1 |    2 |
    | Paris     | Valeur 2 |    1 |
    | Marseille | Valeur 1 |    2 |
    | Marseille | Valeur 2 |    2 |
    +-----------+----------+------+
    --------------
    COMMIT
    --------------
     
    Appuyez sur une touche pour continuer...
    Comme tu peux le constater, le résultat ne sera pas le même.
    La solution qui t'intéresse sera ville --> historique.
    Je sélectionne les villes dont j'ai besoin à l'affichage.
    Je fais une jointure "left outer join" pour indiquer que je veux quand même la ligne des villes, même si l'historique est absent.

    Cordialement.
    Artemus24.
    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  5. #5
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2021
    Messages
    164
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Services de proximité

    Informations forums :
    Inscription : Décembre 2021
    Messages : 164
    Points : 187
    Points
    187
    Par défaut
    Aaaaah oui je comprend mieux!

    Effectivement, ça rend la requête nettement plus claire et moins longue en plus!

    Je vais essayer d'adapter tous ça à mes tables !

  6. #6
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    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 : 6 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Salut PetitBoutDeCode.

    J'ai fait cela à la va vite afin d'illustrer ce que j'ai compris de ta demande.
    Ce n'est pas en soi une requête définitive, juste une base de travail.

    Si ta demande avait été mieux décrite, nous ne serions pas là pour émettre des hypothèses sur la bonne façon de procéder.

    Citation Envoyé par PetitBoutDeCode
    Alors voilà, j'ai trois tables qui sont liées, une qui contient une liste de ville, une autre qui contient l'historique des villes par jour, et une qui contient toutes les actions faites sur un formulaire.
    Pour le lien entre ville et historique, c'est facile à comprendre, vu qu'il n'y a que deux tables.

    Par contre, introduire la troisième table demeure un mystère.
    Que vient faire un formulaire dans le lien ville-historique ?
    Par "action faite", dois-je comprendre que tu historises chaque demande ?
    Et ces demandes concerne a priori quoi ?

    Sans rentrer dans les détails de ta modélisation à trois tables, la table "ville" fait office de table mère.
    Il y a deux tables filles, qui sont "historique" et "formulaire".
    Mais il manque un lien pour unir "historique" à "formulaire".
    C'est là que je ne comprends pas l'utilité de cette table "formulaire".

    N'aurait-il pas été plus judicieux de fusionner les tables "historique" et "formulaire" ?
    Quand une demande est faite, tu effectues une saisie dans le formulaire.
    Ce formulaire va servir à créer une demande qui sera par la suite historisée.
    Ce n'est pas très clair !

    On ne le dira jamais assez, avant de faire quoi que ce soit, il faut d'abord modéliser la base de données.
    Chaque table, chaque déclencheur, chaque requête auront leur utilité et ne seront pas remises en question lors de l'écriture des scripts.
    Sans compter que l'on doit aussi traiter des performances.

    Cordialement.
    Artémus24.
    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  7. #7
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2021
    Messages
    164
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Services de proximité

    Informations forums :
    Inscription : Décembre 2021
    Messages : 164
    Points : 187
    Points
    187
    Par défaut
    Si ta demande avait été mieux décrite, nous ne serions pas là pour émettre des hypothèses sur la bonne façon de procéder.
    En fait, le fait que ces tables sont utilisées au travail, je n'ai pas voulu montrer tous les champs et les noms de table, mais je pensais que montrer un bout de ma requête avec la boucle suffirait à donner une idée du résultat final attendu .

    Ce n'est pas en soi une requête définitive, juste une base de travail.
    Oui c'est un angle d'attaque pour l'instant, mais ça m'aide à voir la requête sous un autre angle! d'autant plus que je ne connaissais pas cette manière de recherche:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    where champ in ('Valeur A','Valeur B')
    C'est vrai qu'à première vue, la solution semble tirée par les cheveux, mais il y a une raison à ça!

    Après, savoir si c'est la meilleure façon de faire, sans doute pas .

    En fait, la table Ville me sert à lister toutes les possibilités que nous avons contractuellement, ensuite, j'ai une personne qui s'occupe d'enregistrer les villes qui sont ouvertes par jour dans la table historique (autre programme) pour que le jour J quand on affiche le formulaire seules les villes souhaitées soient affichées (je préfère ne pas laisser plus de choix que ce qui est nécessaire), l'historique me permet de garder une trace de ce que nous avons fait, si le formulaire était rempli quoi qu'il arrive la question ne se posait pas, mais dans mon cas il se peut que la ville soit prévue et que rien ne soit fait, et ça je veux pouvoir le savoir.

    Du coup la création d'une table historique me semble être adaptée à mon besoin, la seule chose qui ne me plait pas c'est que je fais la jointure sur un champ de type VARCHAR entre ville et historique, je pense le changer quand j'aurais un peu plus de temps pour faire la liaison avec des Integer.

    Et puis j'ai de la redondance en mettant la ville en toute lettre dans les deux tables, mais bon cette partie de la modélisation n'a pas d'influence pour ma demande, enfin je crois .

  8. #8
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    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 : 6 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Salut PetitBoutDeCode.

    Citation Envoyé par PetitBoutDeCode
    je pensais que montrer un bout de ma requête avec la boucle suffirait à donner une idée du résultat final attendu.
    La requête n'est pas suffisante. Il faut aussi le descriptif de tes tables ainsi qu'un jeu d'essai.
    On ne demande pas la totalité de ta base de données, juste la partie concernant le problème.
    Rien ne t'empêche de reproduire le problème sur un exemple réduit.

    Citation Envoyé par PetitBoutDeCode
    j'ai une personne qui s'occupe d'enregistrer les villes qui sont ouvertes par jour dans la table historique
    Ne peut-on pas automatiser cette tâche ?

    Citation Envoyé par PetitBoutDeCode
    l'historique me permet de garder une trace de ce que nous avons fait
    Dans quel but ?

    Citation Envoyé par PetitBoutDeCode
    il se peut que la ville soit prévue et que rien ne soit fait, et ça je veux pouvoir le savoir.
    Le mieux est d'automatiser la tâche et non laisser une personne le faire manuellement.
    Maintenant, tu n'as pas expliqué l'origine de la sélection de la ville.
    Est-ce de la paperasse ? D'où la nécessité d'une intervention humaine.
    Ou bien une origine informatique dans une autre base de données ?

    Cordialement.
    Artemus24.
    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  9. #9
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2021
    Messages
    164
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Services de proximité

    Informations forums :
    Inscription : Décembre 2021
    Messages : 164
    Points : 187
    Points
    187
    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
     
    DROP TABLE IF EXISTS `lien_contrat`;
     
    CREATE TABLE `lien_contrat` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `partenaire` int(11) NOT NULL,
      `type_contrat` varchar(30) COLLATE latin1_general_ci NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
     
    LOCK TABLES `lien_contrat` WRITE;
     
    INSERT INTO `lien_contrat` VALUES (1,1'TYPE 1'),(2,1,'TYPE 2'),(3,1,'TYPE 3');
     
    UNLOCK TABLES;
     
    DROP TABLE IF EXISTS `contrat`;
     
    CREATE TABLE `contrat` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `id_magasin` int(11) DEFAULT NULL,
      `date_saisie` datetime DEFAULT CURRENT_TIMESTAMP,
      `partenaire` int(11) NOT NULL,
      `index_vente` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `iddatesaisie` (`date_saisie`),
      KEY `index_jointure_type_vente` (`index_vente`),
      KEY `index_magasin` (`id_magasin`)
      KEY `index_partenaire` (`partenaire`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
     
     
    LOCK TABLES `contrat` WRITE;
     
    INSERT INTO `contrat` VALUES (1,2,'2022-01-12 09:44:50',1,1),(2,1,'2022-01-12 09:44:50',1,2),(3,3,'2022-01-12 09:44:50',1,3);
    UNLOCK TABLES;
     
    DROP TABLE IF EXISTS `magasin`;
     
    CREATE TABLE `magasin` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `ville` varchar(45) COLLATE latin1_general_ci NOT NULL,
      `id_partenaire` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
     
     
    LOCK TABLES `magasin` WRITE;
     
    INSERT INTO `magasin` VALUES (1,'MARSEILLE',1),(2,'PARIS',1),(3,'TOULOUSE',1),(4,'BORDEAUX',1)
    UNLOCK TABLES;
     
    DROP TABLE IF EXISTS `histo`;
     
    CREATE TABLE `histo` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `magasin` varchar(50) COLLATE latin1_general_ci NOT NULL,
      `date_prod` date NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=7216 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
     
     
    LOCK TABLES `histo` WRITE;
     
    INSERT INTO `histo` VALUES (16,'MARSEILLE','2022-01-12'),(16,'PARIS','2022-01-12'),(16,'TOULOUSE','2022-01-12'),(16,'BORDEAUX','2022-01-12');
    UNLOCK TABLES;
    Voila un exemple complet, enfin j'ai seulement gardé les champs qui nous interessent, donc pour faire un lien complet sur un contrat la jointure se fait comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    contrat.index_vente = lien_contrat.id
    contrat.id_magasin = magasin.id
    magasin.ville = histo.magasin
    Ne peut-on pas automatiser cette tâche ?
    Malheureusement non, le planning peut et change souvent en cours de route, donc je ne peux pas le deviner ou le corriger automatiquement

    Dans quel but ?
    Si jamais je veux voir quel magasin marche mieux qu'un autre, en fonction des jours ou de qui y est par exemple.

    Maintenant, tu n'as pas expliqué l'origine de la sélection de la ville.
    C'est une personne qui choisi en fonction de l'effectif, d'où le fait que je ne peux pas anticiper, et que je dois pouvoir modifier également, en cas de maladie par exemple.

    Pour l'échantillon de données, on a donc 4 villes qui sont dans l'historique du 2022-01-12, et on a en tout 3 types de vente possible, donc quand j'interroge la base, elle doit me renvoyer la liste complète des villes de ce jour plus le nombre de tous les types de ventes qui a eu.

    J'espère avoir répondu correctement a toutes les zones de floues que j'ai pu laisser jusqu'ici

  10. #10
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 381
    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 : 6 381
    Points : 19 065
    Points
    19 065
    Par défaut
    Salut PetitBoutDeCode.

    Il y a plusieurs choses qui ne vont pas.

    a) Vous ne mettez nulle part les déclaratives de vos clefs étrangères.
    Le contrôle de l'intégrité de vos données est remise en question.

    b) pour une clef primaire, il est préférable de mettre "integer unsigned" au lieu de "integer".

    c) Avez-vous un seul magasin par ville ?
    Au cas où vous en auriez plusieurs, je conseille de créer une table ville et d'utiliser une clef étrangère pour pointer sur la table ville.

    d) Pourquoi mettre le nom des villes dans la table "histo" ?
    Comme elles sont déjà référencées dans la table "magasin", autant utiliser une clef étrangère qui pointe sur cette table.

    e) Je ne comprends pas l'utilité de la table "lien_contrat".
    La table "contrat" ne fait aucune référence à la table "lien_contrat". Est-ce un oubli ?

    f) Dois-je comprendre que votre table "lien_contrat" est une table associative ?
    Dans ce cas, il devrait apparaitre toutes les clefs étrangères pointant vers les tables qui sont en liens.

    g) La colonne partenaire est répétée trois fois dans vos quatre tables.
    Est-ce une clef étrangère ? Si oui, avec quelle table ?

    h) La colonne partenaire signifie-t-elle l'entreprise chez qui vous vous fournissez pour un contrat donné ?

    i) avez-vous plusieurs partenaires pour un même magasin ?
    Un partenaire travaille-t-il avec un seul magasin ou avec plusieurs ?

    j) La colonne partenaire étant déjà présente dans la table magasin, il est inutile de la répéter plusieurs fois.

    k) un contrat se fait entre un magasin dans une ville donnée avec un partenaire.
    Avez-vous un contrat avec plusieurs partenaires ?

    l) nommez vos clefs étrangères avec un préfixe. Par exemple FK pour foreigne key.
    Cela permet de les identifier facilement.
    Comme vous n'avez pas déclaré les contraines, il est difficile de savoir si vos colonnes sont des clefs étrangères ou pas.

    k) je n'ai pas trop regardé vos index.
    Il faut mettre un index sur les colonnes servant à la jointure de vos requêtes.
    Il est inutile de créer un index sur la clef étrangère.

    Votre base de données est mal modélisée.
    Eviter les répétitions des colonnes sauf s'il s'agit de clef étrangère.

    Si cela vous intéresse, il existe un sous-forum consacré à la modélisation.
    Il y a des experts qui vous répondrons et se feront un plaisir de normaliser votre base de données.
    Cela permettra de rendre l'accès à vos données plus performantes.

    Cordialement.
    Atemus24.
    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  11. #11
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    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 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    J'ajoute : pourquoi poser des LOCK / UNLOCK avant et après chaque ordre ?
    Une base relationnelle est faite pour être partagée, sauf cas très particulier, il ne faut pas verrouiller la table pour un usage exclusif.

  12. #12
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2021
    Messages
    164
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Services de proximité

    Informations forums :
    Inscription : Décembre 2021
    Messages : 164
    Points : 187
    Points
    187
    Par défaut
    Bonjour,

    Je fais mes jointures soit sur des index, soit sur des clefs primaires(donc forcément indexé), j'ai donné les relations entre les table dans un message précédent, par contre c'est vrai que j'ai oublié le champ partenaire qui lui est en lien sur presque toutes les tables parce que je doit pouvoir tout dissocier par partenaire.

    Si cela vous intéresse, il existe un sous-forum consacré à la modélisation.
    Il me semble que l'on s'écarte du sujet principal, c'est vrai que je suis pas un expert en modélisation, et ma requête peut certainement être améliorée par ce biais, mais ma question était principalement sur la syntaxe de la requête, car si changer la syntaxe d'une requête pour un outils prend quelques minutes, changer toute la structure des bases et modifier chacun des outils qui peut y accéder demande des jours.

    Mais j'entend la remarque, et j'admet que je ne suis pas un expert en modélisation, j'ai tout appris par moi même, donc les bases sur certains sujets peuvent être insuffisantes et je me pencherai sur cette question lorsque le temps me le permettra.

  13. #13
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2021
    Messages
    164
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Services de proximité

    Informations forums :
    Inscription : Décembre 2021
    Messages : 164
    Points : 187
    Points
    187
    Par défaut
    Citation Envoyé par escartefigue Voir le message
    J'ajoute : pourquoi poser des LOCK / UNLOCK avant et après chaque ordre ?
    Bonjour,

    Je n'ai pas choisi de rajouter ce LOCK/UNLOCK, c'est MySQL Dump qui a stocké la procédure de création comme ça, je n'utilise jamais ces fonctions de mon propre chef

  14. #14
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    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 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par PetitBoutDeCode Voir le message
    Il me semble que l'on s'écarte du sujet principal, c'est vrai que je suis pas un expert en modélisation, et ma requête peut certainement être améliorée par ce biais, mais ma question était principalement sur la syntaxe de la requête, car si changer la syntaxe d'une requête pour un outils prend quelques minutes, changer toute la structure des bases et modifier chacun des outils qui peut y accéder demande des jours.

    Mais j'entend la remarque, et j'admet que je ne suis pas un expert en modélisation, j'ai tout appris par moi même, donc les bases sur certains sujets peuvent être insuffisantes et je me pencherai sur cette question lorsque le temps me le permettra.
    En effet : modifier une requête prend le plus souvent très peu de temps comparativement à une refonte même partielle du modèle de données.

    Il faut savoir qu'une base mal modélisée a pour conséquences :
    - des requêtes inutilement complexes et contre performantes
    - des redondances de données qui chargent inutilement l'espace disque et surtout, rendent la cohérence des données hasardeuse
    - des tables dites "obèses" à l'origine d'accès concurrents dégradés

    Pour toutes ces raisons, il est important de se pencher sur la modélisation avant de mettre au point les requêtes, car après, c'est souvent trop tard

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. formatage des requêtes sous psql
    Par Bouboubou dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 03/02/2004, 11h10
  2. Syntaxe PARAMETERS pour requête sous VBA
    Par GAGNON dans le forum VBA Access
    Réponses: 3
    Dernier message: 28/11/2003, 11h39
  3. requête mysql sous php
    Par remi59 dans le forum Débuter
    Réponses: 9
    Dernier message: 03/07/2003, 10h39
  4. Réponses: 3
    Dernier message: 18/05/2003, 00h16
  5. Requete requête sous sybase
    Par eddie dans le forum Sybase
    Réponses: 3
    Dernier message: 02/04/2003, 14h51

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