<?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>Philben - Ms Access &#187; Top</title>
	<atom:link href="https://blog.developpez.com/philben/ptag/top/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/philben</link>
	<description></description>
	<lastBuildDate>Thu, 26 Sep 2013 19:43:53 +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>Top 11 à 15 avec regroupement</title>
		<link>https://blog.developpez.com/philben/p11052/sql-access/top_11_a_15_avec_regroupement</link>
		<comments>https://blog.developpez.com/philben/p11052/sql-access/top_11_a_15_avec_regroupement#comments</comments>
		<pubDate>Mon, 28 May 2012 15:19:14 +0000</pubDate>
		<dc:creator><![CDATA[philben]]></dc:creator>
				<category><![CDATA[SQL - Ms Access]]></category>
		<category><![CDATA[Requête SQL]]></category>
		<category><![CDATA[Top]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Suite au billet précédent, on souhaite obtenir le TOP 11 à 15 des Id (par ordre croissant) liés à chaque personne. Création de la table et insertion des données La structure de la table est un peu différente du billet &#8230; <a href="https://blog.developpez.com/philben/p11052/sql-access/top_11_a_15_avec_regroupement">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Suite au <a href="http://blog.developpez.com/philben/p11047/sql/top-3-aleatoire-avec-regroupement/">billet précédent</a>, on souhaite obtenir le TOP 11 à 15 des Id (par ordre croissant) liés à chaque personne.<br />
<span id="more-26"></span><br />
<strong>Création de la table et insertion des données</strong><br />
La structure de la table est un peu différente du billet précédent pour visualiser facilement la sélection de la requête :</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> CreationTableTop2() <br />
&nbsp; &nbsp;Const cInsert <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> = <span style="color: #800000;">&quot;INSERT INTO tTop2 (Id, Nom) VALUES &quot;</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> i <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, j <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> aNoms <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Variant</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">With</span> DoCmd <br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">False</span> <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; .RunSQL <span style="color: #800000;">&quot;CREATE TABLE tTop2 (Id LONG, Nom CHAR, &quot;</span> &amp; _ <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #800000;">&quot;CONSTRAINT PrimaryKey PRIMARY KEY(Id, Nom));&quot;</span> <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; aNoms = Array(<span style="color: #800000;">&quot;Albert&quot;</span>, <span style="color: #800000;">&quot;Marcel&quot;</span>, <span style="color: #800000;">&quot;Bernard&quot;</span>, <span style="color: #800000;">&quot;Dominique&quot;</span>) <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> i = <span style="color: #151B8D; font-weight: bold;">LBound</span>(aNoms) <span style="color: #8D38C9; font-weight: bold;">To</span> <span style="color: #151B8D; font-weight: bold;">UBound</span>(aNoms) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">For</span> j = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> 25 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;(&quot;</span> &amp; j &amp; <span style="color: #800000;">&quot;,'&quot;</span> &amp; aNoms(i) &amp; <span style="color: #800000;">&quot;');&quot;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">Next</span> j <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> i <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">True</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span> <br />
&nbsp; &nbsp;MsgBox <span style="color: #800000;">&quot;Création terminée&quot;</span> <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p>&nbsp;<br />
<strong>Résultat attendu</strong></p>
<blockquote><p>
Id	Nom<br />
11	Albert<br />
12	Albert<br />
13	Albert<br />
14	Albert<br />
15	Albert<br />
11	Bernard<br />
12	Bernard<br />
&#8230;
</p></blockquote>
<p>&nbsp;<br />
<strong>La requête SQL</strong><br />
Une solution possible est :</p>
<pre style="font-size: 12px;"><font color="black"><br /></font><font color="blue">SELECT </font><font color="gray">* <br /></font><font color="blue">FROM&nbsp;&nbsp; </font><font color="black">ttop2 </font><font color="blue">AS </font><font color="black">T1 <br /></font><font color="blue">WHERE&nbsp;&nbsp;</font><font color="black">id </font><font color="gray">&gt; ALL (</font><font color="blue">SELECT TOP </font><font color="black">10 id <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font color="blue">FROM&nbsp;&nbsp; </font><font color="black">ttop2 T <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font color="blue">WHERE&nbsp;&nbsp;</font><font color="black">T.nom </font><font color="blue">= </font><font color="black">T1.nom <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font color="blue">ORDER&nbsp;&nbsp;BY </font><font color="black">id</font><font color="gray">) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AND </font><font color="black">id </font><font color="gray">&lt;= </font><font color="blue">ANY </font><font color="gray">(</font><font color="blue">SELECT TOP </font><font color="black">15 id <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">FROM&nbsp;&nbsp; </font><font color="black">ttop2 T <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">WHERE&nbsp;&nbsp;</font><font color="black">T.nom </font><font color="blue">= </font><font color="black">T1.nom <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">ORDER&nbsp;&nbsp;BY </font><font color="black">id</font><font color="gray">) <br /></font><font color="blue">ORDER&nbsp;&nbsp;BY </font><font color="black">nom</font><font color="gray">, <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="black">id</font><font color="gray"><br /></font></pre>
<p>&nbsp;<br />
<strong>Explications</strong><br />
La clause Where va filtrer les lignes sur deux critères complémentaires :<br />
Toutes les lignes retournées doivent avoir un Id &gt; à <strong>tous</strong> les Id du TOP 10 du même NOM <strong>ET</strong> un Id &lt;= à <strong>au moins un</strong> Id du TOP 15 du même NOM.<br />
Finalement, seules les Id du TOP 11 à 15 répondent aux deux critères et les lignes correspondantes sont retournées.</p>
<p><strong>Autre solution</strong><br />
Il est possible de substituer <strong>&gt;ALL</strong> et <strong>&lt;=Any</strong> par <strong>Not In</strong> et <strong>In</strong> :</p>
<pre style="font-size: 12px;"><font color="blue">SELECT </font><font color="gray">*<br />&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">FROM </font><font color="black">tTop2 </font><font color="blue">AS </font><font color="black">T1<br />&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">WHERE </font><font color="black">id </font><font color="gray">NOT </font><font color="blue">IN&nbsp;&nbsp;</font><font color="gray">(<br />&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">SELECT TOP </font><font color="black">10 Id <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">FROM </font><font color="black">tTop2 T <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">WHERE </font><font color="black">T.Nom</font><font color="blue">=</font><font color="black">T1.Nom <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">ORDER BY </font><font color="black">Id</font><font color="gray">) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AND </font><font color="black">id </font><font color="blue">IN </font><font color="gray">(<br />&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">SELECT TOP </font><font color="black">15 Id <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">FROM </font><font color="black">tTop2 T <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">WHERE </font><font color="black">T.Nom</font><font color="blue">=</font><font color="black">T1.Nom <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">ORDER BY </font><font color="black">Id</font><font color="gray">)<br />&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="blue">ORDER BY </font><font color="black">Nom</font><font color="gray">, </font><font color="black">id</font><font color="gray">;<br />&nbsp;</font></pre>
<p><strong>Performance</strong><br />
Il est recommandé d&rsquo;indexer sans doublons la colonne &lsquo;Nom&rsquo; sur laquelle porte la clause <strong>Where</strong>.<br />
Compte-tenu de la présence de 2 sous-requêtes, cette requête est adaptée pour une table possédant moins de 1000 lignes&#8230;</p>
<p>Si vous avez d&rsquo;autres solutions, n&rsquo;hésitez pas à les placer en commentaire.</p>
<p>@+</p>
<p>Philippe</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TOP 3 aléatoire avec regroupement</title>
		<link>https://blog.developpez.com/philben/p11047/sql-access/top_3_aleatoire_avec_regroupement</link>
		<comments>https://blog.developpez.com/philben/p11047/sql-access/top_3_aleatoire_avec_regroupement#comments</comments>
		<pubDate>Sat, 26 May 2012 08:50:06 +0000</pubDate>
		<dc:creator><![CDATA[philben]]></dc:creator>
				<category><![CDATA[SQL - Ms Access]]></category>
		<category><![CDATA[Aléatoire]]></category>
		<category><![CDATA[Requête SQL]]></category>
		<category><![CDATA[Top]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Un internaute souhaitait extraire aléatoirement 3 Id d&#8217;une table pour chaque personne. C&#8217;est possible ! Création de la table et insertion des données La table tTop contient une colonne Id (clef primaire) et le nom de la personne Public Function &#8230; <a href="https://blog.developpez.com/philben/p11047/sql-access/top_3_aleatoire_avec_regroupement">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Un internaute souhaitait extraire aléatoirement 3 Id d&rsquo;une table pour chaque personne. C&rsquo;est possible !<br />
<span id="more-25"></span><br />
<strong>Création de la table et insertion des données</strong><br />
La table tTop contient une colonne Id (clef primaire) et le nom de la personne</p>
<div class="codecolorer-container vb blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="vb codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #E56717; font-weight: bold;">Public</span> <span style="color: #E56717; font-weight: bold;">Function</span> CreationTableTop() <br />
&nbsp; &nbsp;Const cInsert <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">String</span> = <span style="color: #800000;">&quot;INSERT INTO tTop (Nom) VALUES &quot;</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> i <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span>, Maxi <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Long</span> <br />
&nbsp; &nbsp;<span style="color: #151B8D; font-weight: bold;">Dim</span> aNoms <span style="color: #151B8D; font-weight: bold;">As</span> <span style="color: #F660AB; font-weight: bold;">Variant</span> <br />
&nbsp;<br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">With</span> DoCmd <br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">False</span> <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; .RunSQL <span style="color: #800000;">&quot;CREATE TABLE tTop (Id AUTOINCREMENT CONSTRAINT PrimaryKey PRIMARY KEY, Nom CHAR);&quot;</span> <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #008000;">'VBA.Array impose que le tableau débute à l'indice 0 (Array de la librairie VBA) <br />
</span> &nbsp; &nbsp; &nbsp;<span style="color: #008000;">'Autre solution : OPTION BASE 0 en tête du module <br />
</span> &nbsp; &nbsp; &nbsp;aNoms = VBA.Array(<span style="color: #800000;">&quot;Albert&quot;</span>, <span style="color: #800000;">&quot;Marcel&quot;</span>, <span style="color: #800000;">&quot;Bernard&quot;</span>) <br />
&nbsp; &nbsp; &nbsp; Maxi = <span style="color: #151B8D; font-weight: bold;">UBound</span>(aNoms) + 1 <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; Randomize <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">For</span> i = 1 <span style="color: #8D38C9; font-weight: bold;">To</span> 50 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.RunSQL cInsert &amp; <span style="color: #800000;">&quot;('&quot;</span> &amp; aNoms(Int(Rnd() * Maxi)) &amp; <span style="color: #800000;">&quot;');&quot;</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #8D38C9; font-weight: bold;">Next</span> i <br />
&nbsp; &nbsp; &nbsp; .RunSQL cInsert &amp; <span style="color: #800000;">&quot;('Dominique');&quot;</span> <br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; .SetWarnings <span style="color: #00C2FF; font-weight: bold;">True</span> <br />
&nbsp; &nbsp;<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #8D38C9; font-weight: bold;">With</span> <br />
&nbsp; &nbsp;MsgBox <span style="color: #800000;">&quot;Création terminée&quot;</span> <br />
<span style="color: #8D38C9; font-weight: bold;">End</span> <span style="color: #E56717; font-weight: bold;">Function</span></div></div>
<p><strong>Difficultés</strong><br />
La première difficulté est d&rsquo;obtenir un top 3 pour chaque Nom. Une solution consiste à filtrer les enregistrements en imposant les Id par Nom grâce à une sous-requête corrélée (WHERE T.Nom=T1.Nom) dans la clause IN :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp;<span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; &nbsp;tTop <span style="color: #993333; font-weight: bold;">AS</span> T1<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp; T1<span style="color: #66cc66;">.</span>Id <span style="color: #993333; font-weight: bold;">IN</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> TOP <span style="color: #cc66cc;">3</span> Id<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; tTop T<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;T<span style="color: #66cc66;">.</span>Nom <span style="color: #66cc66;">=</span> T1<span style="color: #66cc66;">.</span>Nom<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> T<span style="color: #66cc66;">.</span>Id<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> T1<span style="color: #66cc66;">.</span>Nom<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;T1<span style="color: #66cc66;">.</span>Id;</div></div>
<p>Le problème du Top 3 par Nom étant résolu, le plus compliqué reste à faire&#8230; Comment obtenir aléatoirement des Id pour chaque Nom ?<br />
En effet, on souhaite suffisamment d&rsquo;aléatoire pour que la liste des Id différe d&rsquo;un appel à l&rsquo;autre de la requête mais pas trop non plus pour que la sous-requête sorte la même liste des Id pour chaque T1.Id.<br />
L&rsquo;idée de base est d&rsquo;utiliser la fonction RND(T.Id) dans la clause ORDER BY pour trier aléatoirement les enregistrements en sachant que T.Id est unique :</p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp;<span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; &nbsp;tTop <span style="color: #993333; font-weight: bold;">AS</span> T1<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp; T1<span style="color: #66cc66;">.</span>Id <span style="color: #993333; font-weight: bold;">IN</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> TOP <span style="color: #cc66cc;">3</span> Id<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; tTop T<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;T<span style="color: #66cc66;">.</span>Nom <span style="color: #66cc66;">=</span> T1<span style="color: #66cc66;">.</span>Nom<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> Rnd<span style="color: #66cc66;">&#40;</span>T<span style="color: #66cc66;">.</span>Id<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;t<span style="color: #66cc66;">.</span>Id<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> T1<span style="color: #66cc66;">.</span>Nom<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;T1<span style="color: #66cc66;">.</span>Id;</div></div>
<p>Comme vous pouvez le constater, on perd la notion de Top 3 par Nom car pour chaque T1.Id, la sous-requête recalcule une liste d&rsquo;Id différente&#8230;</p>
<p><strong>La requête SQL finale</strong></p>
<div class="codecolorer-container sql blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> &nbsp;<span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; &nbsp;tTop <span style="color: #993333; font-weight: bold;">AS</span> T1<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp; T1<span style="color: #66cc66;">.</span>Id <span style="color: #993333; font-weight: bold;">IN</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> TOP <span style="color: #cc66cc;">3</span> Id<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; tTop T<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;T<span style="color: #66cc66;">.</span>Nom <span style="color: #66cc66;">=</span> T1<span style="color: #66cc66;">.</span>Nom<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> Rnd<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">-</span><span style="color: #66cc66;">&#40;</span> T<span style="color: #66cc66;">.</span>Id <span style="color: #66cc66;">+</span> Timer<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;t<span style="color: #66cc66;">.</span>Id<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> T1<span style="color: #66cc66;">.</span>Nom<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;T1<span style="color: #66cc66;">.</span>Id;</div></div>
<p><strong>Explications</strong><br />
On s&rsquo;appuie sur deux particularités d&rsquo;Access :</p>
<p>La <strong>première</strong> est que si l&rsquo;on passe un nombre négatif en argument à la fonction Rnd(), elle retourne toujours le même nombre aléatoire. Ceci permet d&rsquo;avoir une liste constante d&rsquo;Id pour chaque Nom.</p>
<p>La <strong>deuxième</strong> va nous permettre d&rsquo;obtenir une liste différente d&rsquo;Id entre chaque appel de la requête principale. Pour ajouter un zeste d&rsquo;aléatoire on utilise la fonction Timer() en argument de la fonction Rnd(). Heureusement, Access ne met pas à jour le timer() pendant tout le temps d&rsquo;exécution de la requête. La valeur du timer au démarrage de la requête est conservé jusqu&rsquo;à la fin de son exécution ou de sa prochaine actualisation (dans un formulaire prendre un recordset avec <strong>snapshot</strong> pour éviter une mise à jour via modification du jeu d&rsquo;enregistrements sous-jacent).</p>
<p><strong>Remarques</strong><br />
L&rsquo;ajout d&rsquo;une deuxième colonne de tri (T.Id) dans la sous-requête permet de s&rsquo;assurer que le top 3 retournera toujours que 3 lignes au maximum même si des ex-aequo subsistent après ORDER BY RND(-(T.Id+Timer())).</p>
<p>La présence de la sous-requête entraîne un temps d&rsquo;exécution long de la requête qui sera donc réservée pour des tables ayant peu de lignes (~1000).<br />
@+</p>
<p>Philippe</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
