Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Probleme de rqt un peu compliquée ?

8 réponses
Avatar
albert
Bonjour =E0 tous,

j'ai 2 tables qui contiennent des donn=E9es num=E9riques.
Table1 est compos=E9 de 3 champs et de 850 enregistrements=20
comme suivants :
14 28 96
78 12 87
45 59 67
....
Table 2 est compos=E9 de 6 champs et de 70 000=20
enregistrements comme suivant :
14 54 78 28 65 96
45 14 59 28 96 67
....

je voudrais faire une rqt qui puisse me donner combien de=20
fois chaque enregistrements de Table1 est pr=E9sent dans=20
Table2 et qui aboutirait au r=E9sultat suivant en reprenant=20
mes exemples de Table1 et Table2:
14 28 96 - 2 fois
78 12 87 - 0 fois
45 59 67 - 1 fois

J'ai essay=E9 plusieurs requetes mais ca marche pas du tout.
QQ'un peut m'aider ?

Merci

8 réponses

Avatar
Michel Walsh
Salut,



Les tables ne sont pas efficacement dimensionnées. En effet un champ
implique un "ordre" ( champ f1 n'est pas champ f2) alors que les
enregistrements, entre eux, n'impliquent pas d'ordre. Où je veux en venir,
c'est qu'il n'est pas important, dans notre cas, que 14 soit en premier, en
second, ou en troisième position, donc, il serait préférable d'avoir:


Enreg Valeur 'Champ
1 14
1 28
1 96
2 78
2 12
2 67
3 45
3 59
3 67
4 ...


plutôt que

14 28 96


ce qui est un design qui implique que l'ordre (des valeurs) est important.




Même chose pour la seconde table.


Si le design était comme proposé:


SELECT a.Enreg As Cherché, b.Enreg As TrouvéIci
FROM Table1 INNER JOIN Table2
ON a.Valeur = b.Valeur
GROUP BY a.Enreg, b.Enreg
HAVING COUNT(*)=3



retourne les enregistrements de la table1 qui se retrouvent dans table2
(avec le(s) enregistrement(s) correspondant(s) de la table2). Sauvegarder,
disons, qu1, et alors


SELECT Cherché, COUNT(*) As NombreDeFois
FROM qu1
GROUP BY Cherché



retourne le résultat final.


On peut généralement utiliser un requête de type UNION pour normaliser une
table, mais ici, il semble qu'il manque une clé (qui ferait office de
"enreg").


SELECT (f1+100*f2+10000*f3) As enreg, f1 As valeur FROM table1
UNION ALL
SELECT (f1+100*f2+10000*f3) , f2 FROM table1
UNION ALL
SELECT (f1+100*f2+10000*f3) , f3 FROM table1


peut éventuellement être utilisé pour normaliser la première table.

Pour la seconde table, il faut éviter les erreurs d'arrondissement (non
testé) :

SELECT (f1+CDec(100)* ( f2+CDec(100)*( f3 + CDec(100) *( f4+
CDec(100)*(f5+100*f6) )))) As Enreg, f1 As Valeur FROM table2
UNION ALL
...
UNION ALL
SELECT (f1+CDec(100)* ( f2+CDec(100)*( f3 + CDec(100) *( f4+
CDec(100)*(f5+100*f6) )))) , f6 FROM table2


L'idée étant de produire une "clé", la valeur de la clé est irrelevante,
mais la clé doit exister pour identifier l'enregistrement.




Espérant être utile,
Vanderghast, Access MVP




"albert" wrote in message
news:177e801c44950$b0c9e810$
Bonjour à tous,

j'ai 2 tables qui contiennent des données numériques.
Table1 est composé de 3 champs et de 850 enregistrements
comme suivants :
14 28 96
78 12 87
45 59 67
....
Table 2 est composé de 6 champs et de 70 000
enregistrements comme suivant :
14 54 78 28 65 96
45 14 59 28 96 67
....

je voudrais faire une rqt qui puisse me donner combien de
fois chaque enregistrements de Table1 est présent dans
Table2 et qui aboutirait au résultat suivant en reprenant
mes exemples de Table1 et Table2:
14 28 96 - 2 fois
78 12 87 - 0 fois
45 59 67 - 1 fois

J'ai essayé plusieurs requetes mais ca marche pas du tout.
QQ'un peut m'aider ?

Merci
Avatar
Rv
Salut,

J'ai peut-être une solution. Peut-être car j'ai testé uniquement sur le
jeux d'essai fourni (un peu court), et peut-être car la requête risque
d'être lourde.
Table1(t1c1,t1c2,t1c3)
Table2(t2c1,t2c2,t2c3,t2c4,t2c5,t2c6)
Première requête:
SELECT Table1.T1c1, Table1.T1c2, Table1.T1c3, Count(sr.T1c1)
AS Frequence
FROM Table1 LEFT JOIN
(
SELECT t1c1,t1c2,t1c3
FROM table1, table2
WHERE (t1c1=t2c1 Or t1c1=t2c2 Or t1c1=t2c3 Or t1c1=t2c4 Or
t1c1=t2c5 Or t1c1=t2c6)
AND (t1c2=t2c1 Or t1c2=t2c2 Or t1c2=t2c3 Or t1c2=t2c4 Or
t1c2=t2c5 Or t1c2=t2c6)
AND (t1c3=t2c1 Or t1c3=t2c2 Or t1c3=t2c3 Or t1c3=t2c4 Or
t1c3=t2c5 Or t1c3=t2c6)
) as sr
ON (Table1.T1c3 = sr.T1c3) AND (Table1.T1c2 = sr.T1c2) AND
(Table1.T1c1 = sr.T1c1)
GROUP BY Table1.T1c1, Table1.T1c2, Table1.T1c3
Ca peut être long car:
- On utilise 1 requête et 1 sous requête
- Dans la sous requête il n'y a pas de jointures donc toutes les
combinaisons possibles sont testées : 70 000 * 850.

D'autre part je ne sais pas si pour un même enregistrement on peut
avoir des valeurs identiques dans les champs de la table1. Dans ce cas il y
a pb. Exemple:
Dans table1:
10 10 20
Dans table2
10 20 30 40 50 60
Et la requête renvoi
10 10 20 - 1 fois


A+

Rv

"albert" a écrit dans le message de
news:177e801c44950$b0c9e810$
Bonjour à tous,

j'ai 2 tables qui contiennent des données numériques.
Table1 est composé de 3 champs et de 850 enregistrements
comme suivants :
14 28 96
78 12 87
45 59 67
....
Table 2 est composé de 6 champs et de 70 000
enregistrements comme suivant :
14 54 78 28 65 96
45 14 59 28 96 67
....

je voudrais faire une rqt qui puisse me donner combien de
fois chaque enregistrements de Table1 est présent dans
Table2 et qui aboutirait au résultat suivant en reprenant
mes exemples de Table1 et Table2:
14 28 96 - 2 fois
78 12 87 - 0 fois
45 59 67 - 1 fois

J'ai essayé plusieurs requetes mais ca marche pas du tout.
QQ'un peut m'aider ?

Merci
Avatar
Charles ERNST
Ca sera plus vite torché par programmation que par de requêtes.....


"albert" a écrit dans le message de
news:177e801c44950$b0c9e810$
Bonjour à tous,

j'ai 2 tables qui contiennent des données numériques.
Table1 est composé de 3 champs et de 850 enregistrements
comme suivants :
14 28 96
78 12 87
45 59 67
....
Table 2 est composé de 6 champs et de 70 000
enregistrements comme suivant :
14 54 78 28 65 96
45 14 59 28 96 67
....

je voudrais faire une rqt qui puisse me donner combien de
fois chaque enregistrements de Table1 est présent dans
Table2 et qui aboutirait au résultat suivant en reprenant
mes exemples de Table1 et Table2:
14 28 96 - 2 fois
78 12 87 - 0 fois
45 59 67 - 1 fois

J'ai essayé plusieurs requetes mais ca marche pas du tout.
QQ'un peut m'aider ?

Merci
Avatar
Albert
je te remercie et je vais tester cela

Albert

-----Message d'origine-----
Salut,

J'ai peut-être une solution. Peut-être car j'ai testé
uniquement sur le

jeux d'essai fourni (un peu court), et peut-être car la
requête risque

d'être lourde.
Table1(t1c1,t1c2,t1c3)
Table2(t2c1,t2c2,t2c3,t2c4,t2c5,t2c6)
Première requête:
SELECT Table1.T1c1, Table1.T1c2,
Table1.T1c3, Count(sr.T1c1)

AS Frequence
FROM Table1 LEFT JOIN
(
SELECT t1c1,t1c2,t1c3
FROM table1, table2
WHERE (t1c1=t2c1 Or t1c1=t2c2 Or
t1c1=t2c3 Or t1c1=t2c4 Or

t1c1=t2c5 Or t1c1=t2c6)
AND (t1c2=t2c1 Or t1c2=t2c2 Or
t1c2=t2c3 Or t1c2=t2c4 Or

t1c2=t2c5 Or t1c2=t2c6)
AND (t1c3=t2c1 Or t1c3=t2c2 Or
t1c3=t2c3 Or t1c3=t2c4 Or

t1c3=t2c5 Or t1c3=t2c6)
) as sr
ON (Table1.T1c3 = sr.T1c3) AND
(Table1.T1c2 = sr.T1c2) AND

(Table1.T1c1 = sr.T1c1)
GROUP BY Table1.T1c1, Table1.T1c2,
Table1.T1c3

Ca peut être long car:
- On utilise 1 requête et 1 sous requête
- Dans la sous requête il n'y a pas de
jointures donc toutes les

combinaisons possibles sont testées : 70 000 * 850.

D'autre part je ne sais pas si pour un même
enregistrement on peut

avoir des valeurs identiques dans les champs de la
table1. Dans ce cas il y

a pb. Exemple:
Dans table1:
10 10 20
Dans table2
10 20 30 40 50 60
Et la requête renvoi
10 10 20 - 1 fois


A+

Rv

"albert" a écrit
dans le message de

news:177e801c44950$b0c9e810$
Bonjour à tous,

j'ai 2 tables qui contiennent des données numériques.
Table1 est composé de 3 champs et de 850 enregistrements
comme suivants :
14 28 96
78 12 87
45 59 67
.....
Table 2 est composé de 6 champs et de 70 000
enregistrements comme suivant :
14 54 78 28 65 96
45 14 59 28 96 67
.....

je voudrais faire une rqt qui puisse me donner combien de
fois chaque enregistrements de Table1 est présent dans
Table2 et qui aboutirait au résultat suivant en reprenant
mes exemples de Table1 et Table2:
14 28 96 - 2 fois
78 12 87 - 0 fois
45 59 67 - 1 fois

J'ai essayé plusieurs requetes mais ca marche pas du tout.
QQ'un peut m'aider ?

Merci


.



Avatar
Rv
Ok. Tiens nous au courant du résultat STP!


A+

Rv

"Albert" a écrit dans le message de
news:17c6501c4496e$bde99a90$
je te remercie et je vais tester cela

Albert

-----Message d'origine-----
Salut,

J'ai peut-être une solution. Peut-être car j'ai testé
uniquement sur le

jeux d'essai fourni (un peu court), et peut-être car la
requête risque

d'être lourde.
Table1(t1c1,t1c2,t1c3)
Table2(t2c1,t2c2,t2c3,t2c4,t2c5,t2c6)
Première requête:
SELECT Table1.T1c1, Table1.T1c2,
Table1.T1c3, Count(sr.T1c1)

AS Frequence
FROM Table1 LEFT JOIN
(
SELECT t1c1,t1c2,t1c3
FROM table1, table2
WHERE (t1c1=t2c1 Or t1c1=t2c2 Or
t1c1=t2c3 Or t1c1=t2c4 Or

t1c1=t2c5 Or t1c1=t2c6)
AND (t1c2=t2c1 Or t1c2=t2c2 Or
t1c2=t2c3 Or t1c2=t2c4 Or

t1c2=t2c5 Or t1c2=t2c6)
AND (t1c3=t2c1 Or t1c3=t2c2 Or
t1c3=t2c3 Or t1c3=t2c4 Or

t1c3=t2c5 Or t1c3=t2c6)
) as sr
ON (Table1.T1c3 = sr.T1c3) AND
(Table1.T1c2 = sr.T1c2) AND

(Table1.T1c1 = sr.T1c1)
GROUP BY Table1.T1c1, Table1.T1c2,
Table1.T1c3

Ca peut être long car:
- On utilise 1 requête et 1 sous requête
- Dans la sous requête il n'y a pas de
jointures donc toutes les

combinaisons possibles sont testées : 70 000 * 850.

D'autre part je ne sais pas si pour un même
enregistrement on peut

avoir des valeurs identiques dans les champs de la
table1. Dans ce cas il y

a pb. Exemple:
Dans table1:
10 10 20
Dans table2
10 20 30 40 50 60
Et la requête renvoi
10 10 20 - 1 fois


A+

Rv

"albert" a écrit
dans le message de

news:177e801c44950$b0c9e810$
Bonjour à tous,

j'ai 2 tables qui contiennent des données numériques.
Table1 est composé de 3 champs et de 850 enregistrements
comme suivants :
14 28 96
78 12 87
45 59 67
.....
Table 2 est composé de 6 champs et de 70 000
enregistrements comme suivant :
14 54 78 28 65 96
45 14 59 28 96 67
.....

je voudrais faire une rqt qui puisse me donner combien de
fois chaque enregistrements de Table1 est présent dans
Table2 et qui aboutirait au résultat suivant en reprenant
mes exemples de Table1 et Table2:
14 28 96 - 2 fois
78 12 87 - 0 fois
45 59 67 - 1 fois

J'ai essayé plusieurs requetes mais ca marche pas du tout.
QQ'un peut m'aider ?

Merci


.



Avatar
Michel Walsh
Salut,


Pas sûr, pas sûr.

Pourquoi ne pas tester, tiens.

Charger le code suivant dans une nouvelle base de données (jet).

Intialiser les deux tables, m et n, via la fonction InitialiserLesTables.
(Prends plusieurs minutes, si on demeure en Access, la fenêtre d'exécution
immédiate témoigne de la progression).

Exécuter la méthode TestChronoSQL pour connaître le temps à battre (c'est
le temps que prends une solution basée sur SQL, dans mon cas, cela a pris
340 secondes, soit à peu près six minutes). Comme ce temps est relativement
élevé, il va de soi que le temps réel dépend largement de la charge total du
système d'exploitation (multitâche).

Évidemment, je n'ai pas fourni le temps d'exécution d'une procédure VBA, car
ce n'est pas mon affirmation à moi qu'une telle procédure est plus rapide.



Vanderghast, Access MVP


=========================== Option Compare Database
Option Explicit

Private Type LARGE_INTEGER
lowpart As Long
highpart As Long
End Type

Private Declare Function QueryPerformanceCounter Lib "kernel32"
(lpPerformanceCount As LARGE_INTEGER) As Long
Private Declare Function QueryPerformanceFrequency Lib "kernel32"
(lpFrequency As LARGE_INTEGER) As Long
---------------------------------------
Public Sub InitialiserLesTables()

' Génère des donnés, soit deux tables, m de 850 "tirages" et n, de 70
000 tirages.

Dim i As Long
Dim j As Long
Dim e() As Byte

' On suppose que les numéros tirés sont entre 0 et 100
' (voir TestGetOutOf100 pour méthode utilsée pour générer les
' résultats aléatoirement)


With CurrentDb
' créer les deux tables, sans indexes
.Execute "CREATE TABLE m( enreg LONG, choix BYTE)"
.Execute "CREATE TABLE n( enreg LONG, choix BYTE)"

' remplir la première table
For i = 1 To 750
e = GetOutOf100(6)
For j = 1 To 3
.Execute "INSERT INTO m VALUES(" & i & ", " & e(j) & ")"
Next j
Next i

Debug.Print " Première table terminée, seconde table commence... "

' remplir la seconde table
For i = 1 To 77000
If 0 = i Mod 1000 Then
Debug.Print "... " & i & " enregistrements ajoutés... "
DoEvents
End If

e = GetOutOf100(6)
For j = 1 To 6
.Execute "INSERT INTO n VALUES(" & i & ", " & e(j) & ")"
Next j
Next i

Debug.Print "Seconde table termnée. Création des index..."
' maintenant, créer les indexes

.Execute "CREATE INDEX menreg ON m (enreg)"
.Execute "CREATE INDEX mchoix ON m(choix)"
.Execute "CREATE INDEX nenreg ON n(enreg)"
.Execute "CREATE INDEX nchoix ON n(choix)"

Debug.Print "Index crées, initialisation des tables terminés."
End With


End Sub
------------------------------------

Public Sub TestChronoSQL()
Dim startChrono As LARGE_INTEGER
Dim endChrono As LARGE_INTEGER
Dim frequency As Variant

' Obtenir la fréquence des compteurs de persoformance, sur ce PC
QueryPerformanceFrequency startChrono
frequency = LargeToDec(startChrono)

' Démarrer le chrono, effectuer le processus, fermer le chrono
QueryPerformanceCounter startChrono

Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("SELECT m.enreg, n.enreg " & _
" FROM m INNER JOIN n ON m.Choix = n.Choix " & _
" GROUP BY m.enreg, n.enreg " & _
" HAVING COUNT(*)=3", dbOpenForwardOnly, dbReadOnly)



QueryPerformanceCounter endChrono

' Convertir les compteurs en secondes

MsgBox "Il faut " & (LargeToDec(endChrono) - LargeToDec(startChrono)) /
frequency & " seconde(s)"

End Sub
---------------------------------
Public Function GetOutOf100(HowMany As Long) As Byte()

' Retourner HowMany valeurs différentes entre 0 et 100

' Requière VBA6 ( Access 2000 ou plus récent )
Dim result() As Byte
ReDim result(1 To HowMany) As Byte

Dim i As Long
Dim j As Long
Dim t As Byte
result(1) = CByte(100 * Rnd())
For i = 1 To HowMany
t = CByte(100 * Rnd())
For j = 1 To i - 1
If t = result(j) Then
t = 1 + t Mod 100
j = 0
End If
Next j
result(i) = t
Next i
GetOutOf100 = result

End Function

-------------------------------
Public Function LargeToDec(Arg As LARGE_INTEGER) As Variant

Dim temp As Variant
temp = 4 * CDec(1073741824) ' 2 ^ 32

If Arg.lowpart > 0 Then
LargeToDec = Arg.lowpart + Arg.highpart * temp
Else
LargeToDec = temp + Arg.lowpart + Arg.highpart * temp
End If

End Function
===============================

"Charles ERNST" <charles.ernst(antispam)@micro-gestion.fr> wrote in message
news:
Ca sera plus vite torché par programmation que par de requêtes.....




Avatar
Charles ERNST
Ya maldonne, je ne pensais pas vitesse d'exécution, mais vitesse de
programmation....
Ceci dit, je vais essayer de relever le défi
je vous tiens au courant



"Michel Walsh" a écrit dans le message
de news:%
Salut,


Pas sûr, pas sûr.

Pourquoi ne pas tester, tiens.

Charger le code suivant dans une nouvelle base de données (jet).

Intialiser les deux tables, m et n, via la fonction InitialiserLesTables.
(Prends plusieurs minutes, si on demeure en Access, la fenêtre d'exécution
immédiate témoigne de la progression).

Exécuter la méthode TestChronoSQL pour connaître le temps à battre (c'est
le temps que prends une solution basée sur SQL, dans mon cas, cela a pris
340 secondes, soit à peu près six minutes). Comme ce temps est
relativement

élevé, il va de soi que le temps réel dépend largement de la charge total
du

système d'exploitation (multitâche).

Évidemment, je n'ai pas fourni le temps d'exécution d'une procédure VBA,
car

ce n'est pas mon affirmation à moi qu'une telle procédure est plus rapide.



Vanderghast, Access MVP


=========================== > Option Compare Database
Option Explicit

Private Type LARGE_INTEGER
lowpart As Long
highpart As Long
End Type

Private Declare Function QueryPerformanceCounter Lib "kernel32"
(lpPerformanceCount As LARGE_INTEGER) As Long
Private Declare Function QueryPerformanceFrequency Lib "kernel32"
(lpFrequency As LARGE_INTEGER) As Long
---------------------------------------
Public Sub InitialiserLesTables()

' Génère des donnés, soit deux tables, m de 850 "tirages" et n, de
70

000 tirages.

Dim i As Long
Dim j As Long
Dim e() As Byte

' On suppose que les numéros tirés sont entre 0 et 100
' (voir TestGetOutOf100 pour méthode utilsée pour générer les
' résultats aléatoirement)


With CurrentDb
' créer les deux tables, sans indexes
.Execute "CREATE TABLE m( enreg LONG, choix BYTE)"
.Execute "CREATE TABLE n( enreg LONG, choix BYTE)"

' remplir la première table
For i = 1 To 750
e = GetOutOf100(6)
For j = 1 To 3
.Execute "INSERT INTO m VALUES(" & i & ", " & e(j) & ")"
Next j
Next i

Debug.Print " Première table terminée, seconde table commence... "

' remplir la seconde table
For i = 1 To 77000
If 0 = i Mod 1000 Then
Debug.Print "... " & i & " enregistrements ajoutés... "
DoEvents
End If

e = GetOutOf100(6)
For j = 1 To 6
.Execute "INSERT INTO n VALUES(" & i & ", " & e(j) & ")"
Next j
Next i

Debug.Print "Seconde table termnée. Création des index..."
' maintenant, créer les indexes

.Execute "CREATE INDEX menreg ON m (enreg)"
.Execute "CREATE INDEX mchoix ON m(choix)"
.Execute "CREATE INDEX nenreg ON n(enreg)"
.Execute "CREATE INDEX nchoix ON n(choix)"

Debug.Print "Index crées, initialisation des tables terminés."
End With


End Sub
------------------------------------

Public Sub TestChronoSQL()
Dim startChrono As LARGE_INTEGER
Dim endChrono As LARGE_INTEGER
Dim frequency As Variant

' Obtenir la fréquence des compteurs de persoformance, sur ce PC
QueryPerformanceFrequency startChrono
frequency = LargeToDec(startChrono)

' Démarrer le chrono, effectuer le processus, fermer le chrono
QueryPerformanceCounter startChrono

Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("SELECT m.enreg, n.enreg " & _
" FROM m INNER JOIN n ON m.Choix = n.Choix " & _
" GROUP BY m.enreg, n.enreg " & _
" HAVING COUNT(*)=3", dbOpenForwardOnly, dbReadOnly)



QueryPerformanceCounter endChrono

' Convertir les compteurs en secondes

MsgBox "Il faut " & (LargeToDec(endChrono) - LargeToDec(startChrono))
/

frequency & " seconde(s)"

End Sub
---------------------------------
Public Function GetOutOf100(HowMany As Long) As Byte()

' Retourner HowMany valeurs différentes entre 0 et 100

' Requière VBA6 ( Access 2000 ou plus récent )
Dim result() As Byte
ReDim result(1 To HowMany) As Byte

Dim i As Long
Dim j As Long
Dim t As Byte
result(1) = CByte(100 * Rnd())
For i = 1 To HowMany
t = CByte(100 * Rnd())
For j = 1 To i - 1
If t = result(j) Then
t = 1 + t Mod 100
j = 0
End If
Next j
result(i) = t
Next i
GetOutOf100 = result

End Function

-------------------------------
Public Function LargeToDec(Arg As LARGE_INTEGER) As Variant

Dim temp As Variant
temp = 4 * CDec(1073741824) ' 2 ^ 32

If Arg.lowpart > 0 Then
LargeToDec = Arg.lowpart + Arg.highpart * temp
Else
LargeToDec = temp + Arg.lowpart + Arg.highpart * temp
End If

End Function
=============================== >

"Charles ERNST" <charles.ernst(antispam)@micro-gestion.fr> wrote in
message

news:
Ca sera plus vite torché par programmation que par de requêtes.....








Avatar
Charles ERNST
OK ya pas photo, à condition d'utiliser la structure que vous préconisez et
pas celle décrite dans la question posée.


"Michel Walsh" a écrit dans le message
de news:%
Salut,


Pas sûr, pas sûr.

Pourquoi ne pas tester, tiens.

Charger le code suivant dans une nouvelle base de données (jet).

Intialiser les deux tables, m et n, via la fonction InitialiserLesTables.
(Prends plusieurs minutes, si on demeure en Access, la fenêtre d'exécution
immédiate témoigne de la progression).

Exécuter la méthode TestChronoSQL pour connaître le temps à battre (c'est
le temps que prends une solution basée sur SQL, dans mon cas, cela a pris
340 secondes, soit à peu près six minutes). Comme ce temps est
relativement

élevé, il va de soi que le temps réel dépend largement de la charge total
du

système d'exploitation (multitâche).

Évidemment, je n'ai pas fourni le temps d'exécution d'une procédure VBA,
car

ce n'est pas mon affirmation à moi qu'une telle procédure est plus rapide.



Vanderghast, Access MVP


=========================== > Option Compare Database
Option Explicit

Private Type LARGE_INTEGER
lowpart As Long
highpart As Long
End Type

Private Declare Function QueryPerformanceCounter Lib "kernel32"
(lpPerformanceCount As LARGE_INTEGER) As Long
Private Declare Function QueryPerformanceFrequency Lib "kernel32"
(lpFrequency As LARGE_INTEGER) As Long
---------------------------------------
Public Sub InitialiserLesTables()

' Génère des donnés, soit deux tables, m de 850 "tirages" et n, de
70

000 tirages.

Dim i As Long
Dim j As Long
Dim e() As Byte

' On suppose que les numéros tirés sont entre 0 et 100
' (voir TestGetOutOf100 pour méthode utilsée pour générer les
' résultats aléatoirement)


With CurrentDb
' créer les deux tables, sans indexes
.Execute "CREATE TABLE m( enreg LONG, choix BYTE)"
.Execute "CREATE TABLE n( enreg LONG, choix BYTE)"

' remplir la première table
For i = 1 To 750
e = GetOutOf100(6)
For j = 1 To 3
.Execute "INSERT INTO m VALUES(" & i & ", " & e(j) & ")"
Next j
Next i

Debug.Print " Première table terminée, seconde table commence... "

' remplir la seconde table
For i = 1 To 77000
If 0 = i Mod 1000 Then
Debug.Print "... " & i & " enregistrements ajoutés... "
DoEvents
End If

e = GetOutOf100(6)
For j = 1 To 6
.Execute "INSERT INTO n VALUES(" & i & ", " & e(j) & ")"
Next j
Next i

Debug.Print "Seconde table termnée. Création des index..."
' maintenant, créer les indexes

.Execute "CREATE INDEX menreg ON m (enreg)"
.Execute "CREATE INDEX mchoix ON m(choix)"
.Execute "CREATE INDEX nenreg ON n(enreg)"
.Execute "CREATE INDEX nchoix ON n(choix)"

Debug.Print "Index crées, initialisation des tables terminés."
End With


End Sub
------------------------------------

Public Sub TestChronoSQL()
Dim startChrono As LARGE_INTEGER
Dim endChrono As LARGE_INTEGER
Dim frequency As Variant

' Obtenir la fréquence des compteurs de persoformance, sur ce PC
QueryPerformanceFrequency startChrono
frequency = LargeToDec(startChrono)

' Démarrer le chrono, effectuer le processus, fermer le chrono
QueryPerformanceCounter startChrono

Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("SELECT m.enreg, n.enreg " & _
" FROM m INNER JOIN n ON m.Choix = n.Choix " & _
" GROUP BY m.enreg, n.enreg " & _
" HAVING COUNT(*)=3", dbOpenForwardOnly, dbReadOnly)



QueryPerformanceCounter endChrono

' Convertir les compteurs en secondes

MsgBox "Il faut " & (LargeToDec(endChrono) - LargeToDec(startChrono))
/

frequency & " seconde(s)"

End Sub
---------------------------------
Public Function GetOutOf100(HowMany As Long) As Byte()

' Retourner HowMany valeurs différentes entre 0 et 100

' Requière VBA6 ( Access 2000 ou plus récent )
Dim result() As Byte
ReDim result(1 To HowMany) As Byte

Dim i As Long
Dim j As Long
Dim t As Byte
result(1) = CByte(100 * Rnd())
For i = 1 To HowMany
t = CByte(100 * Rnd())
For j = 1 To i - 1
If t = result(j) Then
t = 1 + t Mod 100
j = 0
End If
Next j
result(i) = t
Next i
GetOutOf100 = result

End Function

-------------------------------
Public Function LargeToDec(Arg As LARGE_INTEGER) As Variant

Dim temp As Variant
temp = 4 * CDec(1073741824) ' 2 ^ 32

If Arg.lowpart > 0 Then
LargeToDec = Arg.lowpart + Arg.highpart * temp
Else
LargeToDec = temp + Arg.lowpart + Arg.highpart * temp
End If

End Function
=============================== >

"Charles ERNST" <charles.ernst(antispam)@micro-gestion.fr> wrote in
message

news:
Ca sera plus vite torché par programmation que par de requêtes.....