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 :

Quelle requête SQL - 2 champs dates


Sujet :

Requêtes MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de tavarlindar
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    262
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 262
    Par défaut Quelle requête SQL - 2 champs dates
    Bonjour à tous,

    Je ne sais pas écrire la requête sql qui me permettrait d'obtenir l'objectif décrit ci-après.

    J'ai 3 tables : contact, demande, commercial définies comme ci-après.
    Contexte simplifié : une personne (un contact) fait une ou plusieurs demandes d'information sur internet. Chaque contact est affecté à un commercial.

    Je souhaite pouvoir effectuer des statistiques par commercial selon une multitude de critères. Parmi ces critères, il y en a un qui est toujours utilisé c'est la période de temps où une demande a été créée .Je gère dans la table demande , une date de création (date_demande).
    Jusque là, aucun problème.

    Seulement voilà, une demande a un statut qui peut prendre 3 valeurs : Pending (valeur par défaut), Signed, Lost. Lorsque le statut change, j'enregistre la date dans un champ date_modif_status de la table demande.
    Je souhaiterais via une seule requête connaître par commercial toutes les demandes signées (Signed) pour une période définie (en fonction de sa date de création date_demande) mais aussi toutes les demandes signées pour cette même période date_modif_status qui concerne des demande créées avant la période définie.

    Ci-dessous définition épurée des 3 tables.

    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
     
    -- 
    -- Structure de la table `contact`
    -- 
     
    CREATE TABLE `contact` (
      `id_contact` int(11) NOT NULL auto_increment,
      `email1` varchar(250) collate utf8_unicode_ci NOT NULL,
      `commercial_id` char(3) character set latin1 NOT NULL default 'XXX',
      `date_creation` datetime NOT NULL default '0000-00-00 00:00:00',
      `date_last_modif` datetime NOT NULL default '0000-00-00 00:00:00',
      `cycle` enum('Leads','Client') character set latin1 NOT NULL default 'Leads',
      PRIMARY KEY  (`id_contact`),
      KEY `email1` (`email1`)
    ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
    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
     
    -- 
    -- Structure de la table `demande`
    -- 
     
    CREATE TABLE `demande` (
      `date_demande` datetime NOT NULL default '0000-00-00 00:00:00',
      `type_prestation` enum('NC','B','BS','BSH','LUX') character set latin1 NOT NULL default 'NC',
      `contact_id` int(11) NOT NULL default '0',
      `commercial_id` int(11) NOT NULL default '0',
      `num_dossier` mediumint(5) unsigned zerofill NOT NULL default '00000',
      `status` enum('Pending','Signed','Lost') character set latin1 NOT NULL default 'Pending',
      `date_modif_status` date default NULL,
      PRIMARY KEY  (`id_demande`),
      KEY `contact_id` (`contact_id`),
      KEY `commercial_id` (`commercial_id`)
    ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    -- 
    -- Structure de la table `commercial`
    -- 
     
    CREATE TABLE `commercial` (
      `id_commercial` char(3) character set latin1 NOT NULL default '',
      `prenom_com` varchar(100) collate utf8_unicode_ci NOT NULL,
      `nom_com` varchar(100) collate utf8_unicode_ci NOT NULL,
      PRIMARY KEY  (`id_commercial`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    Aujourd'hui, pour simplifier mon code, en fonction des critères de sélection choisis, je passe par une VIEW intermédiaire v_stats_DirCom.

    Exemple : pour toutes les demandes créées en mars 2012

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    CREATE OR REPLACE VIEW  v_stats_DirCom AS SELECT c.commercial_id,com.prenom_com,com.nom_com, com.actif,d.id_demande,d.date_demande,d.status, d.num_dossier,d.contact_id,d.commentaireWI,d.site_source, d.source_lien,d.type_prestation,d.tag_suivi_direction,d.commentaires_relance
    FROM demande d LEFT JOIN contact c ON d.contact_id = c.id_contact LEFT JOIN commercial com ON c.commercial_id = com.id_commercial
    WHERE 1 AND YEAR(d.date_demande)='2012' AND MONTH(d.date_demande)='3'
    En suite, j'effectue une requête du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT commercial_id,prenom_com,nom_com,COUNT(date_demande) AS Total_a, 
    SUM(IF(num_dossier='99999',1,0)) AS Impossible_b,
    COUNT(date_demande)-SUM(IF(num_dossier='99999',1,0)) AS Total_c,
    CEILING(  100*( SUM(IF(num_dossier='99999',1,0))/COUNT(date_demande) ) )AS Taux_99999,
    SUM(IF(type_prestation='B' AND num_dossier!='99999',1,0)) AS R_BB,
    SUM(IF(  (type_prestation='BS' OR type_prestation='BSH') AND num_dossier!='99999',1,0)) AS R_CW,
    SUM(IF(type_prestation='LUX' AND num_dossier!='99999',1,0)) AS R_LUX,
    SUM(IF(type_prestation='NC' AND num_dossier!='99999',1,0)) AS R_NC,
    SUM(IF(status='Pending' AND num_dossier!='99999',1,0)) AS R_Pending,
    SUM(IF(status='Signed' AND num_dossier!='99999',1,0)) AS R_SIGNEE
    FROM v_stats_DirCom GROUP BY commercial_id
    ce qui me donne un tableau du type :

    Commercial....|...Total..|..Signed..|....critère X..|...critère Z..|
    AAA.............|...100....|.........3..|..............0..|..............2..|
    BBB.............|....50.... |.........0..|..............9..|..............8..|
    CCC.............|....75....|.........1..|..............4..|..............7..|

    Je souhaiterai avoir une autre colonne où nous aurions toutes les demandes signées pour mars 2012 : sous entendu YEAR(d.date_modif_status)='2012' AND MONTH(d.date_modif_status)='3' AND d.status=''Signed'.

    La difficulté vient du fait que je passe par une requête intermédiaire (VIEW). Cette VIEW me permet de sélectionner ma population mère d'enregistrements en fonction d'une multitude de critère. Une fois ma view créée, je fais mes stats. Je pourrais à priori définir une VIEW qui sélectionnerait toutes mes demandes avec YEAR(d.date_modif_status)='2012' OR (MONTH(d.date_modif_status)='3' AND d.status=''Signed). Mais si je procède ainsi, cela va fausser toutes mes autres stats. Les stats doivent porter sur toutes les demandes pour une période donnée où la date de création est le critère numéro un. Je souhaite seulement pour un critère (status Signed ou pas) avoir en plus le nombre de demandes signées pour cette même période définie (prise en compte du MONTH(d.date_modif_status)='3' AND d.status=''Signed).

    Est-ce possible ?

    Par avance merci.

    tavar

  2. #2
    Membre éclairé Avatar de tavarlindar
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    262
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 262
    Par défaut Redéfinition du problème rencontré
    Bonjour,
    Considérant que ma demande d'aide n'était pas très claire (y compris pour moi même !), je me permets de reposer ma question différemment :

    Est-il possible d'obtenir ce tableau :


    sans passer par une requête du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT commercial_id,com.prenom_com,
    SUM(IF(YEAR(d.date_demande)='2012' AND MONTH(d.date_demande)='6', 1,0)) AS Total_a,
    SUM(IF(STATUS='Pending' AND YEAR(d.date_demande)='2012' AND MONTH(d.date_demande)='6', 1,0)) AS R_Pending,
    SUM(IF(STATUS='Signed' AND YEAR(d.date_demande)='2012' AND MONTH(d.date_demande)='6' ,1,0)) AS R_SIGNEE,
    SUM(IF(STATUS='Signed'AND YEAR(d.date_modif_status)='2012' AND MONTH(d.date_modif_status)='6' ,1,0)) AS R_SIGNEE_PDT_periode
    FROM demandes d LEFT JOIN contacts c ON d.contact_id = c.id_contact LEFT JOIN commerciaux com ON c.commercial_id = com.id_commercial GROUP BY commercial_id
    Pourquoi cette interrogation ?

    L'inconvénient ici, c'est qu'on doit pour chaque ligne de statistique préciser à chaque fois les critères de date. Dans l'exemple simplifié d'ici, c'est gérable, mais pour mes besoins réels, cela devient vite très lourd à mon goût à gérer. En réel, on fait des sélections en fonction d'une multitude de critères (nationalité du contact, type de client, etc).
    Si pour chaque ligne de statistique on doit faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SUM(IF(CRITERE1='toto'  AND CRITERE2='56000' AND ... CRITERE_n ='quelque_chose' AND YEAR(d.date_demande)='2012' AND MONTH(d.date_demande)='6', 1,0)) AS Ma_Statistique
    C'est lourd.

    D'où l'idée de faire une VIEW intermédiaire en amont qui prend tous les critères de sélection y compris les critères de date, ici date_demande qui est la date de création d'une demande.

    Seulement voilà, j'ai besoin de faire apparaitre une statistique et une seule qui s'appuie sur des enregistrements qui ne font pas parti de ma sélection intermédiaire, mais qui prend la même période de référence.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SUM(IF(STATUS='Signed' AND YEAR(d.date_demande)='2012' AND MONTH(d.date_demande)='6' ,1,0)) AS R_SIGNEE,
    indique toutes les demandes créées en juin 2012 et signées en juin 2012

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SUM(IF(STATUS='Signed'AND YEAR(d.date_modif_status)='2012' AND MONTH(d.date_modif_status)='6' ,1,0)) AS R_SIGNEE_PDT_periode
    indique toutes les demandes signées en juin 2012 indépendamment de leur date de création.

    Voilà où j'en suis et fais à ce jour :
    Je crée ma sélection intermédiaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CREATE OR REPLACE VIEW  v_stats AS SELECT c.commercial_id,com.prenom_com,d.id_demande,d.date_demande,d.status,
    d.contact_id,d.date_modif_status
    FROM demandes d LEFT JOIN contacts c ON d.contact_id = c.id_contact LEFT JOIN commerciaux com ON c.commercial_id = com.id_commercial
    WHERE 1 AND YEAR(d.date_demande)='2012' AND MONTH(d.date_demande)='6'
    ce qui donne :


    ensuite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT commercial_id,prenom_com,COUNT(date_demande) AS Total_a, 
    SUM(IF(STATUS='Pending',1,0)) AS R_Pending,
    SUM(IF(STATUS='Signed',1,0)) AS R_SIGNEE
    FROM v_stats GROUP BY commercial_id
    ce qui donne :


    Évidemment, il est impossible d'indiquer toutes les demandes signées en juin 2012, vu que ces demandes ne font pas partie de la View.

    Si on intègre en amont les demandes signées en juin 2012 en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CREATE OR REPLACE VIEW  v_stats2 AS SELECT c.commercial_id,com.prenom_com,d.id_demande,d.date_demande,d.status,
    d.contact_id,d.date_modif_status
    FROM demandes d LEFT JOIN contacts c ON d.contact_id = c.id_contact LEFT JOIN commerciaux com ON c.commercial_id = com.id_commercial
    WHERE 1 AND (YEAR(d.date_demande)='2012' AND MONTH(d.date_demande)='6') OR (YEAR(d.date_modif_status)='2012' AND MONTH(d.date_modif_status)='6')
    on a alors :


    et si on lui applique le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT commercial_id,prenom_com,COUNT(date_demande) AS Total_a, 
    SUM(IF(STATUS='Pending',1,0)) AS R_Pending,
    SUM(IF(STATUS='Signed',1,0)) AS R_SIGNEE
    FROM v_stats2 GROUP BY commercial_id
    on a logiquement :


    ce qui n'est pas le résultat recherché.

    D'où mon interrogation, existe-il un moyen via des unions, où je ne sais quel autre artifice, obtenir ce tableau en conservant l'usage de v_stats:


    ____
    Données


    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
    CREATE TABLE `contacts` (
      `id_contact` int(11) NOT NULL auto_increment,
      `nom` varchar(100) collate utf8_unicode_ci NOT NULL,
      `email1` varchar(250) collate utf8_unicode_ci NOT NULL,
      `commercial_id` char(3) character set latin1 NOT NULL default 'XXX',
      PRIMARY KEY  (`id_contact`),
      KEY `email1` (`email1`)
    ) ENGINE=MyISAM AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=13 ;
     
    -- 
    -- Contenu de la table `contacts`
    -- 
     
    INSERT INTO `contacts` (`id_contact`, `nom`, `email1`, `commercial_id`) VALUES (1, 'ABRAMO', 'ABRAMO@provider.net', 'AAA'),
    (2, 'BRAUN', 'BRAUN@PROVIDER.NET', 'BBB'),
    (3, 'CRISTIANO', 'CRISTIANO@PROVIDER.EU', 'CCC'),
    (4, 'DURANDAL', 'DURANDAL@PROVIDER.COM', 'AAA'),
    (5, 'EL MORICO', 'ELMORI@PROVIDER.COM', 'CCC'),
    (6, 'FRITZ', 'FRITZ@PROVIDER.NET', 'BBB'),
    (7, 'GUNNER', 'GUN@PROVIDER.NET', 'BBB'),
    (8, 'HUNS', 'HUNS@PROVIDER.FR', 'BBB'),
    (9, 'ISILDUR', 'ISI@BETA.COM', 'AAA'),
    (10, 'JERONIMO', 'JEJE@PROVIDER.FR', 'CCC'),
    (11, 'KRISTENSEN', 'KRIKRI@PROVIDER.ES', 'CCC'),
    (12, 'LUMIX', 'LULU@Provider.com', 'DDD');

    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
     
    CREATE TABLE `demandes` (
      `id_demande` int(11) NOT NULL auto_increment,
      `date_demande` datetime NOT NULL default '0000-00-00 00:00:00',
      `contact_id` int(11) NOT NULL default '0',
      `status` enum('Pending','Signed','Lost') character set latin1 NOT NULL default 'Pending',
      `date_modif_status` date default NULL,
      PRIMARY KEY  (`id_demande`),
      KEY `contact_id` (`contact_id`)
    ) ENGINE=MyISAM AUTO_INCREMENT=14 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=14 ;
     
    -- 
    -- Contenu de la table `demandes`
    -- 
     
    INSERT INTO `demandes` (`id_demande`, `date_demande`, `contact_id`, `status`, `date_modif_status`) VALUES (1, '2012-04-02 00:00:00', 1, 'Pending', NULL),
    (2, '2012-05-22 00:00:00', 2, 'Signed', '2012-06-20'),
    (3, '2012-05-06 00:00:00', 3, 'Signed', '2012-06-10'),
    (4, '2012-05-15 00:00:00', 4, 'Signed', '2012-06-27'),
    (5, '2012-06-10 00:00:00', 5, 'Pending', NULL),
    (6, '2012-06-06 00:00:00', 6, 'Pending', NULL),
    (7, '2012-06-13 00:00:00', 7, 'Signed', '2012-06-28'),
    (8, '2012-06-06 00:00:00', 8, 'Pending', NULL),
    (9, '2012-06-10 00:00:00', 9, 'Pending', NULL),
    (10, '2012-06-06 00:00:00', 10, 'Pending', NULL),
    (11, '2012-06-14 00:00:00', 3, 'Signed', '2012-06-19'),
    (12, '2012-06-16 00:00:00', 11, 'Signed', '2012-06-24'),
    (13, '2011-12-27 00:00:00', 12, 'Signed', '2012-06-30')

    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
     
    CREATE TABLE `commerciaux` (
      `id_commercial` char(3) character set latin1 NOT NULL default '',
      `prenom_com` varchar(100) collate utf8_unicode_ci NOT NULL,
      PRIMARY KEY  (`id_commercial`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
     
    -- 
    -- Contenu de la table `commerciaux`
    -- 
     
    INSERT INTO `commerciaux` (`id_commercial`, `prenom_com`) VALUES ('AAA', 'André'),
    ('BBB', 'Béatrice'),
    ('CCC', 'Catherine'),
    ('DDD', 'Dominique');
    Par avance un un grand merci pour votre aide

    Tavar

  3. #3
    Membre Expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Billets dans le blog
    1
    Par défaut
    salut,

    déjà vu que c'est très rare c'est cool de penser à nous donner tout ce qui faut pour tester...

    première remarque... si tu veux de la performance NE JAMAIS utiliser une clé primaire n'étant pas un entier et encore moins faire une jointure avec...

    une fausse bonne idée est de se dire c'est cool je peux utiliser 'aaa' comme identifiant de ligne, c'est autorisé... mais en fait... NON C'EST LE MAL, la clé primaire n'est pas une colonne anodine d'une table... tous ses autres index sont construits à partir d'elle et tout un tas de processus de comptage, etc... et une valeur entière c'est autrement plus simple à manipuler qu'un chaine...

    un entier... c'est un seul accès (entre 8 et 64 bits donc 1 à 8 octets)
    une chaine de caractère c'est une séquence de caractères (qui sont une séquence d'entiers sur 1 octet)

    je te fais pas un dessin sur l'écart de complexité qu'il y a à comparer 2 entiers ou 2 chaines de caractères du coup...

    donc pour identifier une ligne d'une table il est TOUJOURS préférable d'utiliser un entier (et si possible dimensionné au mieux avec le type adéquat pour optimiser les mécanismes de cache qu'utilise le sgbd pour éviter d'aller lire trop souvent les index eux-mêmes

    de même tu perds énormément de performance et de place à stocker ton status comme ça...

    tu ferais mieux d'avoir une table contenant les status possibles et n'est référencée dans la table demandes que par un tinyint ou tinyint unsigned... ça boosterait toutes les manipulations sur cette table...

    évite d'utiliser des mots clés comme nom de colonne sans les anti-quotés: status doit être `status`

    dans tes requêtes précise toujours partout l'alias de la chaque table devant les colonnes quand il y a plusieurs tables en jeux, ça évite de se prendre la tête à relire les définitions de table pour savoir qui est dans quoi...

    tu peux nommer tes clés primaires avec constraint...

    préciser une valeur entre parenthèse ne sert à rien et ne donne pas la taille en octet... c'est uniquement le nom du type qui le fait ici, int qui représente 4 octets... il peut être bon de se poser la question de savoir quelle taille d'entier est la plus adaptée... là encore pour coller un max d'entrée dans les différents caches... note que unsigned te permet d'éviter de ne pas utiliser la moitié négative des valeur parmi celles disponibles pour chaque type entier...

    ton truc passe obligatoirement par de la jointure de sous-tables ou vue pour avoir un assemblage par ligne alors que l'union va te rajouter des lignes

    je suis pas sur que ça soit plus rapide que ta requête car tu est obligé de faire plus de niveau de requête genre:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    select com.id_commercial,com.prenom_com, coalesce(t1.p+t1.s,0) as Total_a,
    	coalesce(t1.p,0) as R_Pending, coalesce(t1.s,0) as R_SIGNEE,coalesce(t2.s,0) as R_SIGNEE_PDT_periode
    from commerciaux com
    left join
    	(select commercial_id,sum(if(`status`='Pending',1,0)) as p,sum(if(`status`='Signed',1,0)) as s
    	FROM demandes d
    	LEFT JOIN contacts c ON d.contact_id = c.id_contact
    	where YEAR(d.date_demande)='2012' AND MONTH(d.date_demande)='6'
    	group by commercial_id) t1 on t1.commercial_id=com.id_commercial
    left join
    	(select commercial_id,sum(if(`status`='Signed',1,0)) as s
    	FROM demandes d
    	LEFT JOIN contacts c ON d.contact_id = c.id_contact
    	where YEAR(d.date_modif_status)='2012' AND MONTH(d.date_modif_status)='6'
    	group by commercial_id) t2 on t2.commercial_id=com.id_commercial;
    la sous requête du premier left join peut être remplacée par ta vue je pense avec peu d'adaptation sur la partie affichage du select étant donné que c'est en grande partie ce qu'elle génère sauf erreur

    par contre, tu vois c'est pas forcément plus simple, compact ou efficace...

    dans tous les cas je te conseille d'encapsuler ces appels paramétriques à ce genre de grosses requête dans une procédure stockée... ça simplifierait au moins tes appels

    d'autres verront peut-être une autre approche... mais je sur pas sur qu'il y en est...

  4. #4
    Membre éclairé Avatar de tavarlindar
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    262
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 262
    Par défaut
    Bonjour ericd69,
    Tout d'abord un très grand Merci.

    Pour répondre à tes remarques :
    sur la clé primaire de la table commerciaux. J'en prends note. Hélas, j'ai conçu cette base il y a 10 ans, et refondre la partie mysql et sur tout la partie applicative est impensable. Dans tous les cas, j'en tiendrai compte pour les extensions.

    Concernant le status. Mysql propose un type ENUM. A quoi bon si c'est moins performant. A l'époque (2002), je ne connaissais pas ENUM, et lors de la conception de la base, j'utilisais justement que des valeurs numériques comme clés primaires avec les bonnes tables associées (civilité = 1,2,3..) avec (1-Mademoiselle,2- Madame, 3-Monsieur). En 2002-2003, il me semble avoir lu, que Mysql optimisait ENUM. J'ai donc ENUMIsé (nouveau verbe!) certains champs. Jamais fait de tests pour voir la différence.
    Avec le temps, J'ENUMise que des champs du type oui ou non. Y ou N pour Y ou N. Cela simplifie les requêtes. Est si grave Docteur ?

    dans tes requêtes précise toujours partout l'alias de la chaque table devant les colonnes quand il y a plusieurs tables en jeux, ça évite de se prendre la tête à relire les définitions de table pour savoir qui est dans quoi...
    ??? Dois je comprendre : mettre le nom de la table devant chaque champs ?


    tu peux nommer tes clés primaires avec constraint...
    ???

    ton truc passe obligatoirement par de la jointure de sous-tables ou vue pour avoir un assemblage par ligne alors que l'union va te rajouter des lignes
    En lisant cette phrase j'ai tout compris.

    dans tous les cas je te conseille d'encapsuler ces appels paramétriques à ce genre de grosses requête dans une procédure stockée... ça simplifierait au moins tes appels
    Je vais étudier la chose. Jamais encore utilisé.

    Un grand merci encore.


    Tavar

  5. #5
    Membre Expert
    Avatar de ericd69
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2011
    Messages
    1 919
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2011
    Messages : 1 919
    Billets dans le blog
    1
    Par défaut
    et oui:
    • une jointure sert à rajouter des colonnes sur les lignes retournées selon des critères
    • une union à rajouter des lignes toutes au même format que les premières retournées selon des critères...

    en réalité, tu peux avoir le même résultat avec l'un ou l'autre mais selon la nature de l'opération il vaut mieux prendre le plus approprié...

    dans ton cas, c'est rajouter des colonnes...

    normalement enum devrait être une association identifiant numérique - valeur texte et mysql utilise l'un à l'autre en fonction du nombre de ligne dans la table (dixit la doc) et ce sans vraiment dire à partir de quand et à quel cout de transformation de la table

    les autres sgbd ne se posent pas la question ils stockent la valeur numérique... de plus, si tu passes par des dump csv avec du load data in file, du coup ça peut ne pas être compatible...

    donc ça se discute...

    pour le nommage des clés primaires:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    constraint nom primary key(id)

    je t'ai dit d'utiliser l'ALIAS du nom de table devant chaque colonne utilisée ou retournée en plus ça évite que mysql te sorte une erreur d'homonymie...

    ça c'est l'avantage des procédures stockées, elles peuvent te permettre d'isoler php et mysql aussi bien niveau sécurité qu'au niveau du code... du coup ça rend plus transparent les changement d'un coté ou de l'autre tant que tu ne changes pas le format de ce qui est échangé...

  6. #6
    Membre chevronné
    Avatar de tse_jc
    Homme Profil pro
    Data Solutions
    Inscrit en
    Août 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Data Solutions
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2010
    Messages : 287
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    Pour répondre tout d'abord à ta question très synthétiquement je vais répondre oui c'est possible.
    Ensuite concernant l'utilisation d'une view pour construire ta requête, je n'en vois pas l'intérêt dans ton contexte précis, quand bien même elle serait updatable, car je me permets de le rappeler MySQL ne gère pas les vues indexées.
    Ensuite, ll va sans dire que ce qu'a dit ericd69 est à prendre en compte, et bien plus que cela, pour pouvoir faire ce que tu souhaites faire avec des performances acceptables, si ton schéma n'est pas solide et adapté (normalisé 4FN et +), avec les contraintes référentielles présentes (idéalement toute la logique métier qu'il y est possible d'intégrer), il sera difficile d'avoir des performances au rendez-vous avec MySQL.
    Ensuite pour la méthodologie tu pourrais passer par des requêtes dérivées avec aggrégations, et ainsi éliminer tes conditions if qui sont contre productives dans un contexte dénormalisé.

    ++

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

Discussions similaires

  1. Requête SQL sur champ DATE
    Par SIADIDL dans le forum SQL
    Réponses: 10
    Dernier message: 13/05/2014, 08h28
  2. [SQL2K] requête SQL, comparer des dates
    Par cortex024 dans le forum MS SQL Server
    Réponses: 10
    Dernier message: 16/03/2006, 14h32
  3. requêtes sur des champs date
    Par wiwi dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 03/02/2006, 14h14
  4. Requête sql regroupement de dates
    Par rocs dans le forum Langage SQL
    Réponses: 1
    Dernier message: 28/07/2005, 16h40
  5. Pb sur une requête SQL (de champ vide)
    Par Marion dans le forum Langage SQL
    Réponses: 3
    Dernier message: 01/07/2004, 11h12

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