<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>blog de f-leb &#187; Access</title>
	<atom:link href="https://blog.developpez.com/f-leb/pcategory/access/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/f-leb</link>
	<description></description>
	<lastBuildDate>Thu, 24 Oct 2013 17:46:38 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>[Access SQL] Trouver l&#8217;enregistrement précédent</title>
		<link>https://blog.developpez.com/f-leb/p11116/access/access_sql_trouver_l_enregistrement_prec</link>
		<comments>https://blog.developpez.com/f-leb/p11116/access/access_sql_trouver_l_enregistrement_prec#comments</comments>
		<pubDate>Mon, 25 Jun 2012 21:38:45 +0000</pubDate>
		<dc:creator><![CDATA[f-leb]]></dc:creator>
				<category><![CDATA[Access]]></category>
		<category><![CDATA[SQL Access]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[C’est tellement simple sous Excel de retrouver la valeur « précédente » qui se trouve à la cellule de la ligne « au-dessus ». Seulement Ici, ma table Access ressemble à ça : J’ai plusieurs véhicules dont je relève le compteur à chaque plein. [Id] est un numéro auto dont je ne peux évidemment pas [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>C’est tellement simple sous Excel de retrouver la valeur « précédente » qui se trouve à la cellule de la  ligne « au-dessus ».<br />
Seulement Ici, ma table Access ressemble à ça :<br />
<img src="http://blog.developpez.com/media/Tbl_Journal.PNG" width="353" height="183" alt="" /></p>
<p>J’ai plusieurs véhicules dont je relève le compteur à chaque plein. [Id] est un numéro auto dont je ne peux  évidemment pas me servir pour retrouver le plein « précédent ».<br />
Dans une table de base de données, les lignes sont un peu comme des billes mélangées dans un sac et retrouver la ligne « précédente » dans ces conditions  n’a pas de sens.</p>
<p>Et pourtant il faudrait obtenir :<br />
<img src="http://blog.developpez.com/media/Result_R_final.PNG" width="451" height="184" alt="" /></p>
<p>Sauriez-vous trouver le jeu de requête/sous-requête pour obtenir le résultat ci-dessus ?<br />
Uniquement avec les assistants, bien sûr ! QBEO*<br />
*<em>Query By Example Only </em><img src="https://blog.developpez.com/f-leb/wp-includes/images/smilies/icon_wink.gif" alt=";-)" class="wp-smiley" /></p>
<p><span id="more-11"></span><br />
On commence par une requête intermédiaire <strong>R_DatePrecedente</strong>.</p>
<p>Celle-ci nécessite une auto-jointure sur la table [Journal]. Dans l’assistant il faut ajouter une deuxième fois la table Journal qui prendra automatiquement l’alias [journal_1].<br />
Pour chaque plein d’un véhicule, on recherche les dates des pleins précédents et on retient la date du plein le plus récent (avec Max(Journal_1.DatePlein)).</p>
<p><img src="http://blog.developpez.com/media/R_DatePrecedente.PNG" width="548" height="291" alt="" /></p>
<p><img src="http://blog.developpez.com/media/Result_R_DatePrecedente.PNG" width="361" height="146" alt="" /></p>
<p>La requête <strong>R_final</strong> reprend la requête précédente comme sous-requête :<br />
<img src="http://blog.developpez.com/media/R_final.PNG" width="453" height="282" alt="" /><br />
<img src="http://blog.developpez.com/media/Result_R_final.PNG" width="451" height="184" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Access SQL]  Count(*) ou Count([Nom_de_colonne]) ?</title>
		<link>https://blog.developpez.com/f-leb/p10498/access/access_sql_count_ou_count_nom_de_colonne</link>
		<comments>https://blog.developpez.com/f-leb/p10498/access/access_sql_count_ou_count_nom_de_colonne#comments</comments>
		<pubDate>Sun, 13 Nov 2011 10:10:14 +0000</pubDate>
		<dc:creator><![CDATA[f-leb]]></dc:creator>
				<category><![CDATA[Access]]></category>
		<category><![CDATA[SQL Access]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Tout le monde connaît l’opération d’agrégation SQL count permettant de compter le nombre d’occurrences renvoyées par une requête. Dans le QBE d’Access, après avoir opéré le regroupement, on sélectionne l’opération Compte avec le champ de la table concerné. Par exemple, si on souhaite connaître le nombre de commandes par client : dont la traduction en [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Tout le monde connaît l’opération d’agrégation SQL <a href="http://office.microsoft.com/fr-fr/access-help/fonction-count-HA001231438.aspx">count</a> permettant de compter le nombre d’occurrences renvoyées par une requête.<br />
<span id="more-10"></span></p>
<p>Dans le QBE d’Access, après avoir opéré le regroupement, on sélectionne  l’opération <em>Compte</em> avec le champ de la table concerné.<br />
Par exemple, si on souhaite connaître le nombre de commandes par client :</p>
<p><img src="http://blog.developpez.com/media/Blog11_qbeR1_01.PNG" width="348" height="307" alt="" /></p>
<p>dont la traduction en SQL, nous donne l’opération :<br />
<code class="codecolorer text default"><span class="text">…Count(Commandes.[N° commande]) AS [CompteDeN° commande]</span></code></p>
<p>Or on peut lire dans l’aide Access:</p>
<blockquote><p><em>Count(*)</em> s&rsquo;exécute beaucoup plus rapidement que <em>Count([nom_de_colonne]</em>)</p></blockquote>
<p>Ce qui fait que l’on devrait plutôt utiliser le caractère générique *, et écrire quelque chose de normalement plus performant avec:<br />
<img src="http://blog.developpez.com/media/Blog11_qbeR1_avecstar.PNG" width="461" height="305" alt="" /> </p>
<p>Soit en SQL,:<br />
<code class="codecolorer text default"><span class="text">…Count(*) AS [CompteDeN° commande]</span></code></p>
<p>Notre requête présente toutefois  l’inconvénient de ne pas présenter les clients qui n’ont jamais commandé. Pour tenter d’y remédier, on modifie dans un premier temps la requête avec une jointure externe LEFT (type &laquo;&nbsp;2&nbsp;&raquo; dans le QBE) :<br />
<img src="http://blog.developpez.com/media/Blog11_qbeR2.PNG" width="462" height="332" alt="" /></p>
<p><strong>qui retourne un résultat faux</strong> avec un nombre de commandes égal à 1 pour les clients qui n’ont jamais commandé. Cela est logique puisque le but de la jointure <em>LEFT</em> est justement de retourner au moins un enregistrement par client.</p>
<p>Pour s’en sortir il suffit de consulter l’aide à nouveau :</p>
<blockquote><p>La fonction <em>Count(expr)</em> ne compte pas les enregistrements possédant des champs <em>Null</em> sauf si l’argument <em>expr</em> est remplacé par le caractère générique astérisque (*)</p></blockquote>
<p>Si on écrit, la requête :</p>
<p><img src="http://blog.developpez.com/media/Blog11_qbeR3.PNG" width="353" height="311" alt="" /> </p>
<p>La requête retourne, pour les clients qui n’ont jamais commandé, un enregistrement avec [N° commande]=<em>Null</em>.
</p>
<p><img src="http://blog.developpez.com/media/Blog11_qbeR3_result.PNG" width="429" height="323" alt="" /> </p>
<p>Il suffit de regrouper par client et de compter le nombre de champ [N° Commande] non à Null.</p>
<p><strong>Il faut donc utiliser dans ce cas précis <em>count([N°Commande])</em>  et non <em>count(*)</em>:</strong></p>
<p><img src="http://blog.developpez.com/media/Blog11_qbeR4.PNG" width="366" height="326" alt="" /></p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT &nbsp;<br />
&nbsp; Clients.[Code client], Clients.Société, <br />
&nbsp; Count(Commandes.[N° commande]) AS [CompteDeN° commande] <br />
FROM Clients LEFT JOIN Commandes <br />
&nbsp; &nbsp; ON Clients.[Code client] = Commandes.[Code client] <br />
GROUP BY Clients.[Code client], Clients.Société;</div></div>
</p>
<p><img src="http://blog.developpez.com/media/Blog11_qbeR4_result.PNG" width="511" height="227" alt="" /></p>
<p><strong>Conclusion :</strong></p>
<p>Je reprends <a href="http://office.microsoft.com/fr-fr/access-help/fonction-count-HA001231438.aspx">l&rsquo;aide Access</a>:</p>
<blockquote><p>
La fonction <em>Count(expr)</em>  ne compte pas les enregistrements possédant des champs <em>Null</em> sauf si l’argument <em>expr</em> est remplacé par le caractère générique astérisque (*). Si vous utilisez un astérisque, la fonction <em>Count</em> calcule le nombre total des enregistrements, y compris ceux qui contiennent des champs <em>Null</em>.<br />
<em>Count(*)</em> s&rsquo;exécute beaucoup plus rapidement que <em>Count([nom_de_colonne])</em>.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Access SQL] Avec ou sans sous-requêtes ?</title>
		<link>https://blog.developpez.com/f-leb/p10252/access/access_sql_avec_ou_sans_sous_requetes</link>
		<comments>https://blog.developpez.com/f-leb/p10252/access/access_sql_avec_ou_sans_sous_requetes#comments</comments>
		<pubDate>Sun, 04 Sep 2011 21:06:05 +0000</pubDate>
		<dc:creator><![CDATA[f-leb]]></dc:creator>
				<category><![CDATA[Access]]></category>
		<category><![CDATA[SQL Access]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[On s’intéresse aux résultats de la Ligue 1 En fonction des scores des rencontres, on souhaite une requête qui renverrait pour chaque équipe les nombres de victoires, nuls et défaites à domicile. 1ère solution: avec des sous-requêtes corrélées, SELECT DISTINCT equipe.idequipe, &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; equipe.nomequipe, &#160; &#160; &#160; &#160; [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>On s’intéresse aux résultats de la Ligue 1 <img src="https://blog.developpez.com/f-leb/wp-includes/images/smilies/icon_smile.gif" alt=":-)" class="wp-smiley" /></p>
<p><img src="http://blog.developpez.com/media/Blog9_Relations.PNG" width="321" height="186" alt="" /></p>
<p>En fonction des scores des rencontres, on souhaite une requête qui renverrait pour chaque équipe les nombres de victoires, nuls et défaites <strong>à domicile</strong>.</p>
<p><img src="http://blog.developpez.com/media/Blog9_R_GNPDomicile.PNG" width="540" height="196" alt="" /><br />
<span id="more-9"></span><br />
<strong>1ère solution:</strong> avec des sous-requêtes corrélées,</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT DISTINCT equipe.idequipe, &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; equipe.nomequipe, &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (SELECT COUNT(*) &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FROM &nbsp; [Match] m1 &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;WHERE &nbsp;m1.idequipedomicile = equipe.idequipe &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND m1.scoreequipedomicile &gt; m1.scoreequipeext) AS gagne &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (SELECT COUNT(*) &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FROM &nbsp; [Match] m1 &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;WHERE &nbsp;m1.idequipedomicile = equipe.idequipe &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND m1.scoreequipedomicile = m1.scoreequipeext) AS nul, &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (SELECT COUNT(*) &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FROM &nbsp; [Match] m1 &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;WHERE &nbsp;m1.idequipedomicile = equipe.idequipe &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND m1.scoreequipedomicile &lt; m1.scoreequipeext) AS perdu &nbsp;<br />
FROM &nbsp; equipe &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp;LEFT JOIN [Match] &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ON equipe.idequipe = match.idequipedomicile;</div></div>
<p><img src="http://blog.developpez.com/media/Blog9_R1.PNG" width="575" height="246" alt="" /></p>
<p><strong>2ème solution:</strong> sans sous-requêtes, dans une requête qui regroupe les rencontres à domicile de chaque équipe,</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT equipe.idequipe, &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp;equipe.nomequipe, &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp;SUM(Iif(scoreequipedomicile &gt; scoreequipeext, 1, 0)) AS gagne, &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp;SUM(Iif(scoreequipedomicile = scoreequipeext, 1, 0)) AS nul, &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp;SUM(Iif(scoreequipedomicile &lt; scoreequipeext, 1, 0)) AS perdu &nbsp;<br />
FROM &nbsp; equipe &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp;LEFT JOIN [Match] &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ON equipe.idequipe = match.idequipedomicile &nbsp;<br />
GROUP &nbsp;BY equipe.idequipe, &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; equipe.nomequipe;</div></div>
<p><img src="http://blog.developpez.com/media/Blog9_R2.PNG" width="735" height="262" alt="" /></p>
<p><code class="codecolorer text default"><span class="text">…SUM(Iif(scoreequipedomicile &gt; scoreequipeext, 1, 0)) AS gagne, …</span></code><br />
En cas de victoire à domicile, l’expression Iif retourne 1 et 0 sinon. Puis on somme les victoires.<br />
Même principe pour les nuls et défaites.</p>
<p>Et vous, quelle solution vous préférez, 1 ou 2 ?</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>[Access SQL] Modifier un tri</title>
		<link>https://blog.developpez.com/f-leb/p10240/access/access_sql_modifier_un_tri</link>
		<comments>https://blog.developpez.com/f-leb/p10240/access/access_sql_modifier_un_tri#comments</comments>
		<pubDate>Wed, 31 Aug 2011 21:01:16 +0000</pubDate>
		<dc:creator><![CDATA[f-leb]]></dc:creator>
				<category><![CDATA[Access]]></category>
		<category><![CDATA[SQL Access]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Je voudrais les pays classés par ordre alphabétique à l’exception de la France qui serait en tête de liste : 1ère solution : avec une requête UNION SELECT t.idpays, &#160; &#160; &#160; &#160; &#160;t.nompays &#160; FROM &#160; (SELECT 0 AS indextri, &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;idpays, &#160; &#160; &#160; &#160; &#160; [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Je voudrais les pays classés par ordre alphabétique à l’exception de la  France qui serait en tête de liste :</p>
<p>     <img src="http://blog.developpez.com/media/blog8_trialpha.PNG" width="361" height="140" alt="" /><br />
<span id="more-8"></span><br />
<strong>1ère solution :</strong> avec une requête UNION</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT t.idpays, &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp;t.nompays &nbsp;<br />
FROM &nbsp; (SELECT 0 AS indextri, &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;idpays, &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nompays &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp; pays &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp;nompays = &quot;France&quot; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; UNION ALL &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; SELECT 1 AS indextri, &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;idpays, &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nompays &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp; pays &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp;nompays &lt;&gt; &quot;France&quot;) AS t &nbsp;<br />
ORDER &nbsp;BY t.indextri, &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; t.nompays;</div></div>
<p><strong>2ème solution:</strong> avec un champ calculé placé dans la clause ORDER BY</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT pays.idpays, &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp;pays.nompays &nbsp;<br />
FROM &nbsp; pays &nbsp;<br />
ORDER &nbsp;BY Iif(nompays = &quot;France&quot;, 0, 1), &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pays.nompays;</div></div>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Access SQL]  Jointure externe avec critère</title>
		<link>https://blog.developpez.com/f-leb/p10238/access/sql_access_jointure_externe_avec_critere</link>
		<comments>https://blog.developpez.com/f-leb/p10238/access/sql_access_jointure_externe_avec_critere#comments</comments>
		<pubDate>Wed, 31 Aug 2011 17:10:18 +0000</pubDate>
		<dc:creator><![CDATA[f-leb]]></dc:creator>
				<category><![CDATA[Access]]></category>
		<category><![CDATA[SQL Access]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Prenons un exemple simplifié de gestion des cotisations d’adhérents : On veut pour l’année 2011 la liste de tous les adhérents avec le montant de la cotisation ou la mention « pas de cotisation » s’ils n’ont pas cotisé en 2011. Évidemment la 1ère tentative avec la jointure naturelle par défaut ne convient pas : [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Prenons un exemple simplifié de gestion des cotisations d’adhérents :<br />
<img src="http://blog.developpez.com/media/blog7_Schema.PNG" width="315" height="125" alt="" /> <img src="http://blog.developpez.com/media/blog7_Adherent.PNG" width="335" height="411" alt="" /></p>
<p>On veut pour l’année 2011 la liste de tous les adhérents avec le montant de la cotisation ou la mention « pas de cotisation » s’ils n’ont pas cotisé en 2011.<br />
<img src="http://blog.developpez.com/media/blog7_ResultatFinal.PNG" width="422" height="99" alt="" /><br />
<span id="more-7"></span><br />
Évidemment la 1ère tentative avec la jointure naturelle par défaut ne convient pas :<br />
<img src="http://blog.developpez.com/media/blog7_RJointureINNER.PNG" width="614" height="257" alt="" /><br />
<img src="http://blog.developpez.com/media/blog7_RJointureINNER_Resultat.PNG" width="441" height="83" alt="" /></p>
<p><strong>PERDU !</strong></p>
<p>On pense à faire une jointure externe de type « 2 ».<br />
Une nouvelle tentative :<br />
<img src="http://blog.developpez.com/media/blog7_RJointureLEFT_SansWHERE.PNG" width="607" height="465" alt="" /><br />
<img src="http://blog.developpez.com/media/blog7_RJointureLEFT_SansWHERE_Resultat.PNG" width="520" height="183" alt="" /></p>
<p>Si on complète avec le critère de restriction sur l’année 2011 :<br />
<img src="http://blog.developpez.com/media/blog7_RJointureLEFT_AvecWHERE.PNG" width="589" height="253" alt="" /><br />
<img src="http://blog.developpez.com/media/blog7_RJointureLEFT_AvecWHERE_Resultat.PNG" width="362" height="82" alt="" /></p>
<p><strong>PERDU !!</strong></p>
<p>Comme le décrit <a href="http://blog.developpez.com/cinephil/p9571/bases-de-donnees/langage-sql/jointure-externe-et-condition-de-restric/#more9571">Cinephil dans son blog</a>:</p>
<blockquote><p>Quand on fait une jointure externe à gauche et qu&rsquo;on pose une restriction (dans le WHERE) sur la table de droite, c&rsquo;est comme si on faisait une jointure interne !</p></blockquote>
<p>La solution, toujours proposée par CinePhil :</p>
<blockquote><p>… il faut déplacer les conditions de restriction sur la table externe du WHERE vers la condition de jointure.</p></blockquote>
<p>Comme la modification qui suit n’est pas interprétable dans le QBE d’Access, j’édite la requête précédente en mode SQL…<br />
<img src="http://blog.developpez.com/media/blog7_RJointureLEFT_AvecWHERE_SQL.PNG" width="308" height="114" alt="" /><br />
… et je la modifie en déplaçant le critère WHERE dans la condition de jointure ON (attention aux parenthèses):<br />
<img src="http://blog.developpez.com/media/blog7_RSolution.PNG" width="485" height="100" alt="" /><br />
<img src="http://blog.developpez.com/media/blog7_RSolution_Resultat.PNG" width="392" height="121" alt="" /></p>
<p><strong>GAGNÉ !!</strong></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Access] La relation de type « un à un » (suite)</title>
		<link>https://blog.developpez.com/f-leb/p10126/access/access_la_relation_de_type_l_un_a_un_r_s</link>
		<comments>https://blog.developpez.com/f-leb/p10126/access/access_la_relation_de_type_l_un_a_un_r_s#comments</comments>
		<pubDate>Tue, 12 Jul 2011 21:57:52 +0000</pubDate>
		<dc:creator><![CDATA[f-leb]]></dc:creator>
				<category><![CDATA[Access]]></category>
		<category><![CDATA[Modélisation des données]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[suite à l&#8217;article: [Access] La relation de type « un à un », voici pourtant ce qu’on peut lire dans le livre : Access 2007 et VBA (paru en 03/2008) par Bernard Minot, Jean-Michel Léry dont l’extrait ci-dessous est disponible chez Google books à la page 42: Les relations de 1 à 1 Nous supposons [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>suite à l&rsquo;article: <a href="http://blog.developpez.com/f-leb/p9637/access/la-relation-de-type-l-un-a-un-r">[Access] La relation de type « un à un »</a>,</p>
<p>voici pourtant ce qu’on peut lire dans le livre : Access 2007 et VBA (paru en 03/2008)<br />
par Bernard Minot, Jean-Michel Léry</p>
<p>dont l’extrait ci-dessous est disponible chez <a href="http://books.google.com/books?id=1dIika_ZI9kC&amp;pg=PA42&amp;lpg=PA42&amp;dq=%22un+%C3%A0+un%22+access&amp;source=bl&amp;ots=2r6oTZWcRG&amp;sig=fe-MgaVJjn2redMugR7IfWp5J04&amp;hl=en&amp;ei=GzYcTqSfB8PCtAbj17nmBg&amp;sa=X&amp;oi=book_result&amp;ct=result&amp;resnum=2&amp;ved=0CBwQ6AEwATge#v=onepage&amp;q&amp;f=false">Google books à la page 42</a>:</p>
<blockquote><p><strong>Les relations de 1 à 1</strong><br />
Nous supposons la présence de deux tables contenant des données relatives, par exemple, à vos contacts professionnels, d’une part, et à vos contacts personnels, d’autre part. La conjugaison de ces deux tables peut se décliner ainsi :<br />
&#8211; Un contact professionnel correspond soit à zéro, soit à un et au plus un contact personnel (un partenaire commercial peut aussi être un ami !) ;<br />
&#8211; Un contact personnel correspond soit à zéro, soit à un et au plus un contact personnel (même raison).<br />
Nous sommes ici devant une relation de un à un. A priori, et pourvu que les uns et les autres n’aient pas de rôle particulier à jouer dans le système d’information à mettre en place, il n’y a aucune raison pour ne pas fusionner purement et simplement les deux fichiers. La seule opération à mettre en place avant ladite fusion consiste à créer une propriété particulière à la table qui fusionne les deux fichiers pour distinguer les « commerciaux » des « amis personnels ». <strong>Cet exemple peut être généralisé : les relations de un à un dans une base bien conçue n’existent pas(1).</strong><br />
<strong><br />
(1). Seul cas de figure possible : si la table doit compter plus de 255 colonnes, il sera nécessaire de créer une table « fille ».</strong></p></blockquote>
<p>grrrmffff&#8230;</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[Access SQL] le cas DISTINCTROW</title>
		<link>https://blog.developpez.com/f-leb/p9793/access/sql_access_le_cas_distinctrow</link>
		<comments>https://blog.developpez.com/f-leb/p9793/access/sql_access_le_cas_distinctrow#comments</comments>
		<pubDate>Tue, 08 Mar 2011 16:51:28 +0000</pubDate>
		<dc:creator><![CDATA[f-leb]]></dc:creator>
				<category><![CDATA[Access]]></category>
		<category><![CDATA[SQL Access]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Si vous avez déjà cherché des solutions pour éliminer les doublons dans vos tables/requêtes, vous connaissez probablement déjà le mot-clé DISTINCT qui fait partie de la norme SQL. Mais connaissez-vous le prédicat Access DISTINCTROW ? Certains, oui : DISTINCTROW ou l’exemple parfait de l’absurdité d’Access ! Rideau… Je développe un peu quand même en prenant [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><em>Si vous avez déjà cherché des solutions pour éliminer les doublons dans vos tables/requêtes, vous connaissez probablement déjà le mot-clé DISTINCT qui fait partie de la norme SQL.</p>
<p>Mais connaissez-vous le prédicat Access DISTINCTROW ?</p>
<p>Certains, oui :<br />
<a href="http://sqlpro.developpez.com/cours/sqlaz/erreurs/#L8.1">DISTINCTROW ou l’exemple parfait de l’absurdité d’Access !</a></p>
<p>Rideau… <img src="https://blog.developpez.com/f-leb/wp-includes/images/smilies/icon_wink.gif" alt=";-)" class="wp-smiley" /><br />
</em><br />
<span id="more-6"></span><br />
Je développe un peu quand même en prenant un exemple pratique avec la requête suivante (qui change un peu du traditionnel schéma : Client-1&#8212;&#8211;&#8734;-Commande):<br />
<img src="http://blog.developpez.com/media/DistinctRow01.PNG" width="507" height="269" alt="" /></p>
<p>On recherche les élèves qui ont exprimé au moins une fois le souhait de suivre le module n°7 dans leurs trois premiers vœux. Parmi ces élèves on ne retiendra que ceux qui n’ont jamais pu obtenir d’affectation sur ce module.</p>
<p>La requête  retourne 59 lignes en tout :<br />
<img src="http://blog.developpez.com/media/DistinctRow02.PNG" width="314" height="274" alt="" /></p>
<p>Les doublons s’expliquent ici car lors des différentes rotations (NumRotation=1,2,…), certains élèves peuvent redemander ce module n°7 tant qu’ils n’ont pu l’obtenir (par manque de place car la demande est forte sur ce module !).</p>
<p><strong>1ère tentative d’élimination des doublons :</strong></p>
<p>Une bonne vielle clause DISTINCT :<br />
<img src="http://blog.developpez.com/media/DistinctRow_03.PNG" width="333" height="184" alt="" /></p>
<blockquote><p>Vous pouvez utiliser la propriété <em>UniqueValues</em> lorsque vous souhaitez écarter les enregistrements qui contiennent des données en double dans les champs affichés en mode Feuille de données. Par exemple, si le résultat d’une requête inclut plusieurs champs, la combinaison des valeurs de tous les champs doit être unique pour un enregistrement donné à inclure dans les résultats.</p></blockquote>
<p>Au niveau SQL :<br />
<code class="codecolorer text default"><span class="text">SELECT DISTINCT Eleve.idEleve, Eleve.NomEleve, Eleve.PrenomEleve FROM …</span></code></p>
<p>La requête ne retourne plus que 41 enregistrements sans doublon.<br />
<img src="http://blog.developpez.com/media/DistinctRow_04.PNG" width="312" height="133" alt="" /></p>
<p>En clair, l’opérateur DISTINCT agit donc en omettant les doublons sur la combinaison des colonnes affichées (ici le triplet{idEleve,NomEleve,PrenomEleve} ).</p>
<p><strong>2ème tentative d’élimination des doublons :</strong></p>
<p><img src="http://blog.developpez.com/media/DistinctRow_05.png" width="333" height="185" alt="" /></p>
<blockquote><p>Vous pouvez utiliser la propriété <em>UniqueRecords </em>lorsque vous souhaitez omettre les données basées sur des enregistrements en double entiers, pas uniquement des champs en double. Microsoft Access considère qu’un enregistrement est unique pour autant que la valeur d’un champ dans l’enregistrement diffère de la valeur du même champ dans un autre enregistrement.</p></blockquote>
<p>Au niveau SQL :<br />
<code class="codecolorer text default"><span class="text">SELECT DISTINCTROW Eleve.idEleve, Eleve.NomEleve, Eleve.PrenomEleve FROM …</span></code></p>
<p>Notez que nous sommes dans le cadre d’utilisation normale de la clause DISTINCTROW :</p>
<blockquote><p>DISTINCTROW n&rsquo;a d&rsquo;effet que si vous sélectionnez des champs pour certaines tables utilisées dans la requête, mais pas toutes. DISTINCTROW est ignorée si votre requête n&rsquo;inclut qu&rsquo;une seule table, ou si vous produisez des champs à partir de toutes les tables.</p></blockquote>
<p>La requête omettant les données basées sur des enregistrements en double de la table Eleve (et pas seulement les doublons sur les seules colonnes affichées), celle-ci retournera …les mêmes lignes qu’avec la clause DISTINCT, rigoureusement…</p>
<p><strong>Conclusion :</strong></p>
<p>La différence entre DISTINCT et DISTINCTROW est donc subtile et a de quoi embrouiller le développeur qui dans ce cas particulier a déjà deux solutions pour obtenir le même résultat :<br />
<code class="codecolorer text default"><span class="text">SELECT DISTINCT Eleve.idEleve, Eleve.NomEleve, Eleve.PrenomEleve FROM …</span></code><br />
ou bien,<br />
<code class="codecolorer text default"><span class="text">SELECT DISTINCTROW Eleve.idEleve, Eleve.NomEleve, Eleve.PrenomEleve FROM …</span></code></p>
<p>L’écart entre les durées moyennes d’exécution des deux requêtes avec DISTINCT et DISTINCTROW est négligeable sur mon jeu de données. Rien à attendre sur les performances en faveur de l’un ou l’autre a priori.</p>
<p>Le connaisseur pourra quand même rétorquer que le DISTINCTROW agissant au niveau de l’enregistrement, la requête devient « updatable » (eupedatabeul, miseàjourable) contrairement à celle avec DISTINCT. </p>
<p>Au fait, DISTINCTROW est spécifique à Access et ne fait pas partie de la norme SQL. Comment faire avec du SQL standard ?</p>
<p>On peut se contenter de DISTINCT ou bien on emploie l’opérateur EXISTS :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT Eleve.idEleve, Eleve.NomEleve, Eleve.PrenomEleve &nbsp;<br />
FROM Eleve <br />
WHERE EXISTS <br />
( <br />
&nbsp; SELECT 0 FROM VoeuEleve LEFT JOIN AffectationEleve <br />
&nbsp; ON VoeuEleve.idEleve=AffectationEleve.idEleve <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AND VoeuEleve.idModule=AffectationEleve.idModule <br />
&nbsp; WHERE VoeuEleve.idModule=7 AND VoeuEleve.OrdreVoeu&lt;=3 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND AffectationEleve.idEleve IS NULL <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND VoeuEleve.idEleve=Eleve.idEleve <br />
) ;</div></div>
<p>Certes, on sort des assistants pour rédiger cette requête…<br />
<img src="http://blog.developpez.com/media/DistinctRow_06.PNG" width="603" height="249" alt="" /><br />
…mais le temps d’exécution de la requête avec EXISTS me semble bien meilleur et les données peuvent aussi être mises à jour…</p>
<p>Si vous avez un retour d’expérience avec DISTINCTROW, n’hésitez pas à en faire profiter ici…</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[Access SQL] Requêtes complexes avec l’assistant QBE (Exercice 2)</title>
		<link>https://blog.developpez.com/f-leb/p9790/access/access_sql_requetes_complexes_avec_l_ass_2</link>
		<comments>https://blog.developpez.com/f-leb/p9790/access/access_sql_requetes_complexes_avec_l_ass_2#comments</comments>
		<pubDate>Sun, 06 Mar 2011 14:15:37 +0000</pubDate>
		<dc:creator><![CDATA[f-leb]]></dc:creator>
				<category><![CDATA[Access]]></category>
		<category><![CDATA[SQL Access]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[La règle du jeu est la même que pour l’exercice 1. Seules les requêtes avec le label Q.B.E.O(*) sont admises ici… (*) Q.B.E.O : Query By Example Only (0% SQL) -&#60;8-) mouarf Proposition de corrigé en page 3 Comme chacun sait, la base de données du forum Dvp est gérée sous Access ;-). Afin également [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><em>La règle du jeu est la même que pour l’exercice 1.</p>
<p>Seules les requêtes avec le label Q.B.E.O(*) sont admises ici…</p>
<p>(*) Q.B.E.O : Query By Example Only (0% SQL)  -&lt;8-)  mouarf</em></p>
<p><strong>Proposition de corrigé en page 3</strong><br />
<span id="more-3"></span><br />
Comme chacun sait, la base de données du forum Dvp est gérée sous Access ;-).</p>
<p>Afin également de réviser le fonctionnement du forum, on va s’intéresser ici au calcul des points de chacun des membres.<br />
Voir : <a href="http://www.developpez.net/forums/d988591/club-professionnels-informatique/evolutions-club/nouveaute-nouveau-systeme-rangs-base-points/">[Nouveauté] Nouveau système de rangs basé sur des points</a><br />
<img src="http://blog.developpez.com/media/Exo2_Relations.PNG" width="611" height="283" alt="" /></p>
<p>Nous avons donc des membres,<br />
<img src="http://blog.developpez.com/media/Exo2_Membres.PNG" width="219" height="161" alt="" /><br />
qui ouvrent des discussions, chaque discussion comportant des messages rédigés par des membres.<br />
<img src="http://blog.developpez.com/media/Exo2_Discussion.PNG" width="684" height="344" alt="" /></p>
<p>Grâce au récent système de votes, chaque message peut comporter des votes positifs et négatifs :<img src="http://blog.developpez.com/media/Exo2_votes.PNG" width="78" height="28" alt="" /></p>
<p><img src="http://blog.developpez.com/media/Exo2_VotesMessage.PNG" width="689" height="310" alt="" /></p>
<p>Le champ <em>[Vote]</em> prendra les valeurs +1 ou -1, l’application prendra soin de vérifier qu’un membre ne puisse voter pour ses propres messages. Un membre ne peut voter pour un même message qu’une seule fois.</p>
<p>Les discussions qui ont le tag [Résolu] sont dans la table [TagRésolu] avec le membre qui a posé le tag:<br />
<img src="http://blog.developpez.com/media/Exo2_TagResolu.PNG" width="336" height="98" alt="" /></p>
<p>La discussion est généralement taguée <em>[Résolu]</em> par son auteur (celui qui a posté le 1er message de la discussion) mais elle peut l’être par un autre membre ayant les droits requis (modérateur,…) qui récupèrera alors le point.</p>
<p>Voir le message <a href="http://www.developpez.net/forums/d988591-11/club-professionnels-informatique/evolutions-club/nouveaute-nouveau-systeme-rangs-base-points/#post5588187">ici</a>:</p>
<blockquote><p>… Désormais le forum &laquo;&nbsp;mémorise&nbsp;&raquo; qui utilise le bouton [Résolu] et donc, désormais, si c&rsquo;est un modérateur qui utilise le bouton sur votre discussion à votre place, c&rsquo;est le modérateur qui sera crédité d&rsquo;1 point et non plus vous !</p></blockquote>
<p>La requête au final doit retourner le total de points de chaque membre du forum (sans arrondi):<br />
<img src="http://blog.developpez.com/media/Exo2_Rfinal.PNG" width="287" height="163" alt="" /><br />
Le mode de calcul sera le suivant (allégé par rapport au système réel sur Dvp, pas de note sur les discussions, pas de point pour les articles ou les billets blogs…):<br />
<a href="http://www.developpez.net/forums/d988591/club-professionnels-informatique/evolutions-club/nouveaute-nouveau-systeme-rangs-base-points/">[Nouveauté] Nouveau système de rangs basé sur des points</a></p>
<blockquote><p><strong>0 point</strong> par discussion créée<br />
<strong>0 point</strong> par réponse dans votre propre discussion<br />
<strong>1 point</strong> par réponse dans une discussion qui n&rsquo;est pas la vôtre<br />
<strong>1 point</strong> par discussion marquée résolue<br />
<strong>1 point</strong> par vote positif reçu sur un de vos messages<br />
<strong>-1 point</strong> par vote négatif reçu sur un de vos messages<br />
<strong>0,1 point</strong> par vote message envoyé</p></blockquote>
<p>On considèrera que le créateur de la discussion est le membre qui a rédigé le 1er message (celui avec le champ <em>[NumeroOrdre]</em>=1).</p>
<p>A vous de jouer… Lien vers <a href="http://www.mediafire.com/?s6amm4vraeazd6g">Exercice2.mdb</a></p>
<p><strong>Note :</strong> l’usage de la fonction <em>Nz</em> est autorisé <img src="https://blog.developpez.com/f-leb/wp-includes/images/smilies/icon_wink.gif" alt=";-)" class="wp-smiley" /></p>
<blockquote><p>Nz(Expression ; ValeurSiNull)</p>
<p>Ex : Nz([UnChamp] ; 0)<br />
Si [UnChamp] est Null, la fonction Nz renvoie le nombre zéro</p></blockquote>
<p><strong>Proposition de corrigé</strong></p>
<p>Voici les « vues » intermédiaires dont nous avons besoin.</p>
<blockquote><p>1 point par discussion marquée résolue<br />
0,1 point par vote message envoyé</p></blockquote>
<p><img src="http://blog.developpez.com/media/R_PtsTagResolu&amp;PtsVotesEffectues.png" width="679" height="267" alt="" /></p>
<blockquote><p>1 point par vote positif reçu sur un de vos messages<br />
-1 point par vote négatif reçu sur un de vos messages</p></blockquote>
<p><img src="http://blog.developpez.com/media/R_PtsVotesRecus.PNG" width="307" height="325" alt="" /></p>
<blockquote><p>0 point par discussion créée<br />
0 point par réponse dans votre propre discussion<br />
1 point par réponse dans une discussion qui n&rsquo;est pas la vôtre</p></blockquote>
<p>On commence par sélectionner le membre créateur de chaque discussion ouverte :<br />
<img src="http://blog.developpez.com/media/R_MembreCreateurDiscussion.PNG" width="430" height="314" alt="" /></p>
<p>Pour chaque discussion, on élimine tous les messages rédigés par son créateur (idMembreOuverture  Est Null). Puis on compte les messages restants regroupés par membre et qui rapportent des points à leurs auteurs.<br />
<img src="http://blog.developpez.com/media/R_PtsMessages.PNG" width="481" height="332" alt="" /></p>
<p>Et enfin, on additionne tous ces points :<br />
<img src="http://blog.developpez.com/media/R_PtsFinal.PNG" width="710" height="410" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Access SQL] Requêtes complexes avec l’assistant QBE (Exercice 1)</title>
		<link>https://blog.developpez.com/f-leb/p9651/access/access_sql_requetes_complexes_avec_l_ass_1</link>
		<comments>https://blog.developpez.com/f-leb/p9651/access/access_sql_requetes_complexes_avec_l_ass_1#comments</comments>
		<pubDate>Sun, 09 Jan 2011 20:09:49 +0000</pubDate>
		<dc:creator><![CDATA[f-leb]]></dc:creator>
				<category><![CDATA[Access]]></category>
		<category><![CDATA[SQL Access]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Le but des exercices proposés dans cette rubrique est de s’exercer à la construction de requêtes complexes sous Access. J’essaierais donc de proposer des exercices couvrant le maximum des possibilités offertes par le langage SQL Access, c.-à-d. des jointures internes, externes, des fonctions de regroupement, des filtres, des sous-requêtes, des analyses croisées etc. Par contre [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><em> Le but des exercices proposés dans cette rubrique est de s’exercer à la construction de requêtes complexes sous Access.<br />
J’essaierais donc de proposer des exercices couvrant le maximum des possibilités offertes par le langage SQL Access, c.-à-d. des jointures internes, externes, des fonctions de regroupement, des filtres, des sous-requêtes, des analyses croisées etc.</p>
<p>Par contre j’aimerais que les solutions aux exercices restent à la portée du débutant.<br />
Le gros code SQL tout rouge et qui tâche est donc proscrit ici tout comme l’usage de fonctions VBA personnalisées. </p>
<p>Seules les solutions obtenues avec l’assistant QBE (Query By Example) d’Access seront retenues.</em><br />
<span id="more-5"></span><br />
<strong>Exercice 1 :</strong></p>
<p>Il s’agit donc des interventions de membres sur des forums (liste des interventions arrêtée à l’année 2010).<br />
La requête <em>R_final</em> doit retourner le nombre de forums dans lesquels sont intervenus chacun des membres en 2010.<br />
<img src="http://blog.developpez.com/media/exercice1.png" width="846" height="694" alt="" /></p>
<p>Pour corser l’affaire, nous excluons les membres qui ne sont jamais intervenus (cas du membre n°6 inactif) et ceux dont l’année de la dernière intervention date d’avant 2009 (cas du membre n°4 dont la dernière intervention date de 2008).</p>
<p>Je mets un lien vers la base de départ : <a href="http://www.mediafire.com/?u4pwbh9gvv8v42k">Exercice1.zip</a></p>
<p><strong>Proposition de corrigé</strong></p>
<p>Il faut donc passer par quelques « vues » intermédiaires.</p>
<p><strong>1ère étape : déterminer les membres « actifs » (ceux qui ont au moins une intervention depuis 2009)</strong><br />
On commence par sélectionner les membres qui n’ont pas d’intervention ou dont la date de dernière  intervention remonte avant 2009.<br />
<img src="http://blog.developpez.com/media/R_MembresSansIntervRecentes.PNG" width="372" height="306" alt="" /></p>
<p>On peut maintenant obtenir les membres « actifs » (requête de non-correspondance):<br />
<img src="http://blog.developpez.com/media/R_MembresActifs.PNG" width="589" height="271" alt="" /></p>
<p><strong><br />
2ème étape : déterminer les forums où sont intervenus les membres au cours de l’année 2010</strong><br />
On sélectionne les couples {membre, forum} sur les interventions de l’année 2010. Comme un membre peut intervenir plusieurs fois dans le même forum, on ne retient que les couples {membre, forum} distincts.<br />
<img src="http://blog.developpez.com/media/R_MembreForumEn2010.png" width="472" height="282" alt="" /></p>
<p><strong><br />
Dernière étape : le comptage des forums parmi les membres actifs</strong><br />
La requête R_Final  compte le nombre souhaité de forums :<br />
<img src="http://blog.developpez.com/media/R_final2.PNG" width="553" height="299" alt="" /></p>
<p>N’hésitez pas à laisser vos commentaires…</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>[Access 2010] Programmer des contraintes avec les évènements de tables (macro de données)</title>
		<link>https://blog.developpez.com/f-leb/p9640/access/programmer_des_contraintes_avec_les_even</link>
		<comments>https://blog.developpez.com/f-leb/p9640/access/programmer_des_contraintes_avec_les_even#comments</comments>
		<pubDate>Thu, 06 Jan 2011 19:13:34 +0000</pubDate>
		<dc:creator><![CDATA[f-leb]]></dc:creator>
				<category><![CDATA[Access]]></category>
		<category><![CDATA[Nouveautés Access 2010]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Access dans sa version 2010 dispose enfin d’un mécanisme s’apparentant aux triggers (déclencheurs) bien connus chez les SGBD poids lourds (SQL Server, Oracle,…). Prenons un exemple avec le schéma des relations : Étant donné un découpage de la région en territoires comportant des adresses. Les territoires sont attribués à des colporteurs et dans le cadre [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Access dans sa version 2010 dispose enfin d’un mécanisme s’apparentant aux triggers (déclencheurs) bien connus chez les SGBD poids lourds (SQL Server, Oracle,…).<br />
<img src="http://blog.developpez.com/media/trigger1.png" width="189" height="203" alt="" /><br />
<span id="more-1"></span></p>
<p>Prenons un exemple avec le schéma des relations :<br />
<img src="http://blog.developpez.com/media/trigger2.png" width="605" height="292" alt="" /></p>
<p>Étant donné un découpage de la région en territoires comportant des adresses.<br />
Les territoires sont attribués à des colporteurs et dans le cadre de leurs attributions, ceux-ci effectuent des visites.</p>
<p>Les contraintes à vérifier ici sont les suivantes :</p>
<blockquote><p><strong>C1)</strong> Une visite effectuée dans le cadre d’une attribution doit être réalisée parmi les adresses faisant partie des adresses du territoire attribué<br />
<strong>C2)</strong> On ne rend pas visite à une adresse si la seule personne qui y habite est un colporteur.
</p></blockquote>
<p>La contrainte à programmer est donc sur le couple {idAttribution, idAdresse} de la table Visite.</p>
<p><strong>Une première tentative…</strong></p>
<p>La seule contrainte C1 peut être assurée grâce au jeu de l’intégrité référentielle en modifiant le schéma (adresses et attributions identifiées relativement au territoire):<br />
<img src="http://blog.developpez.com/media/trigger3.png" width="604" height="311" alt="" /></p>
<p>Pas forcément simple à gérer au niveau de l’IHM et il reste encore la contrainte C2 à programmer.</p>
<p><strong>2ème tentative  avec une macro de données :</strong></p>
<p>Enregistrons une première requête,<br />
<img src="http://blog.developpez.com/media/trigger4.png" width="605" height="232" alt="" /><br />
qui retourne les couples (adresse, attribution) possibles. J&rsquo;ai retiré les occurrences où l&rsquo;adresse est celle d&rsquo;un colporteur (critère PersonneQuiEstColporteur.idPersonne Est Null).</p>
<p>Sur l&rsquo;évènement « Avant Modification » de la table Visite, on écrit la macro commentée suivante:<br />
<img src="http://blog.developpez.com/media/trigger5.png" width="605" height="330" alt="" /></p>
<p>On teste…<br />
<img src="http://blog.developpez.com/media/trigger6.png" width="398" height="215" alt="" /></p>
<p>Soit l’adresse n°4 ne fait pas partie du territoire de l’attribution n°3, soit elle en fait éventuellement partie mais c’est un colporteur qui est enregistré à cette adresse.</p>
<p>CQFD : l’action de donnée « DéclencherErreur » invalide la saisie/modification de la visite n°12 dans la table.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
