Problème avec une requête SQL comprenant "in"

Problème avec une requête SQL comprenant "in" - SQL/NoSQL - Programmation

Marsh Posté le 08-10-2004 à 09:36:25    

Bonjour,
 
voici mon problème j'essaye d'optimiser la page d'accueil d'un site web, comportant des requêtes sur des bases SQL Server et Access.  
 
Je suis passé d'une boucle for (en ASP) qui comportait 21 select, à une seule requête SQL + une autre qui est la suivante (toute simple sous Access):
 
"select societe, id from comptes where id in(1323,1827,3865,3909,987,1014,1015,1016,1017,1018,1020,1022,1023,1024,1025,3041)"
 
L'ordre dans lequel apparaissent les valeurs dans la clause "in" est l'ordre dans lequel je souhaiterai que cette requête me retourne les valeurs, c'est à dire :
 
societe / id
truc1 / 1323
truc2 / 1827
Etc...
 
Cependant la requête me retourne les résultats dans l'ordre où elle trouve les valeurs dans la base, à savoir :
 
societe / id
trucZ / 987
trucW / 1014
 
Etc... j'ai regardé dans les clauses group by et order by mais je ne parviens pas à trouver la formulation nécessaire à ma requête pour obtenir le résultat que je souhaite. Auriez-vous la solution ou quelques pistes à me soumettre ?  
 
Merci d'avance

Reply

Marsh Posté le 08-10-2004 à 09:36:25   

Reply

Marsh Posté le 08-10-2004 à 09:38:10    

L'ordre que tu souhaites correspond à quelquechose? :??:
Si c'est l'ordre alphabétique des noms, il te suffit de faire un "order by societe", hein...


Message édité par skeye le 08-10-2004 à 09:38:25

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 08-10-2004 à 09:55:16    

skeye a écrit :

L'ordre que tu souhaites correspond à quelquechose? :??:
Si c'est l'ordre alphabétique des noms, il te suffit de faire un "order by societe", hein...


 
Oui l'ordre que je souhaite obtenir en résultat est l'ordre indiqué dans la clause "in" qui est le résultat d'une autre requête. Je ne veux pas d'un ordonnancement sur la société, ou autre ordonnancement croissant, etc... Je souhaiterai avoir en résultat les valeurs dans l'ordre des "id" de la clause "in". C'est à dire :  
 
Id / Société
1323 nom_société correspondante
1827 nom_société correspondante
3865 nom_société correspondante
3909 nom_société correspondante
987 nom_société correspondante
 
Voilà
 
Merci

Reply

Marsh Posté le 08-10-2004 à 10:02:04    

Et tu peux pas combiner tes 2 requêtes?
Au pire (mais c'est laid) tu peux stocker ton ordre dans une table temporaire et ajouter une jointure dessus, mais sinon je vois pas trop...
Sous Oracle je t'aurais bien proposé un decode, mais je sais pas ce que permettent sql server et access de ce coté.


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 08-10-2004 à 10:10:09    

skeye a écrit :

Et tu peux pas combiner tes 2 requêtes?
Au pire (mais c'est laid) tu peux stocker ton ordre dans une table temporaire et ajouter une jointure dessus, mais sinon je vois pas trop...
Sous Oracle je t'aurais bien proposé un decode, mais je sais pas ce que permettent sql server et access de ce coté.


 
Bon j'ai demandé à mon collègue entre temps qui avait déjà rencontré le problème, et voici la solution effective et qui marche :
 
"select id, societe from comptes where id in(1323,1827,3865,3909,987,1014,1015,1016,1017,1018,1020,1022,1023,1024,1025,3041) order by id=1323, id=1827, id=3865, id=3909, id=987, id=1014, id=1015, id=1016, id=1017, id=1018, id=1020, id=1022, id=1023, id=1024, id=1025, id=3041"
 
qui retourne bien les résultats dans l'ordre de la clause "in".  
 
Voilà, merci pour ton intérêt skeye.

Reply

Marsh Posté le 08-10-2004 à 10:57:53    

J'aurai appris un truc! [:ddr555]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 08-10-2004 à 11:23:12    

housk, oublie cette solution, pour deux raisons :
1) Le IN est extrêment lent et limité en nombre d'éléments. Selon l'évolution de ton application, tu risques très certainement de te retrouver limité plus tard.
2) Si le IN provient d'une autre requête triée, alors l'ordre des valeurs peut être récupéré en utilisant le même critère de tri.
 
Peux-tu poster tes deux requêtes, qu'on te fournisse la bonne requête à utiliser à la place ? Non seulement ce sera plus rapide, mais surtout ça permettra la mise à jour automatique et sans limitations de la liste des sociétés à afficher, sans jamais toucher une ligne de code.

Reply

Marsh Posté le 08-10-2004 à 11:23:40    

skeye a écrit :

J'aurai appris un truc! [:ddr555]


Moi aussi :D
 
Mais quand je vois le truc, je me dit que j'aurais mieu fait de ne pas l'apprendre :whistle:

Reply

Marsh Posté le 08-10-2004 à 11:48:53    

skeye a écrit :

Et tu peux pas combiner tes 2 requêtes?
Au pire (mais c'est laid) tu peux stocker ton ordre dans une table temporaire et ajouter une jointure dessus, mais sinon je vois pas trop...
Sous Oracle je t'aurais bien proposé un decode, mais je sais pas ce que permettent sql server et access de ce coté.


 
Sql server => CASE
Access => IIF  :whistle:

Reply

Marsh Posté le 08-10-2004 à 11:49:05    

Arjuna a écrit :

housk, oublie cette solution, pour deux raisons :
1) Le IN est extrêment lent et limité en nombre d'éléments. Selon l'évolution de ton application, tu risques très certainement de te retrouver limité plus tard.
2) Si le IN provient d'une autre requête triée, alors l'ordre des valeurs peut être récupéré en utilisant le même critère de tri.
 
Peux-tu poster tes deux requêtes, qu'on te fournisse la bonne requête à utiliser à la place ? Non seulement ce sera plus rapide, mais surtout ça permettra la mise à jour automatique et sans limitations de la liste des sociétés à afficher, sans jamais toucher une ligne de code.


 
Ok je te mets ici les 2 requêtes SQL, la première sous SQL Server, la seconde sous Access. Attention c'est noyé dans du code ASP :
 
"sql8="SELECT top 16 mesure.id_truc, SUM(type_mesure.point) AS total_point, COUNT(mesure.id) AS total_clic, mesure.date_inscription FROM         mesure INNER JOIN type_mesure ON mesure.type_mesure = type_mesure.id WHERE     (mesure.date_mesure between '"&debut&"' and '"&fin&"') GROUP BY mesure.id_truc, mesure.date_inscription ORDER BY total_point DESC, mesure.date_inscription"
 
puis
 
sql82="select societe, id from comptes where id in("&rs16("id_truc" )
rs16.movenext
do while not rs16.EOF
   sql82 = sql82 & "," & rs16("id_truc" )
   rs16.movenext
loop
sql82=sql82 & " )"
rs17.open sql82, conn2, 3
if rs17.recordcount > 0 then
   rs17.movefirst
   i=1
   do while not rs17.EOF%>
      <%=i%>- mon bla bla html avec le résultat de chaque enregistrementbr>
  <%  rs17.movenext  
      i=i+1
   loop
   rs17.close
   set rs17=nothing
else %>Classement non établi<% end if
 
ceci pour remplacer à la base (optimiser dirais-je) :
 
strsql="SELECT  mesure.id_truc, SUM(type_mesure.point) AS total_point, COUNT(mesure.id) AS total_clic, mesure.date_inscription FROM         mesure INNER JOIN type_mesure ON mesure.type_mesure = type_mesure.id WHERE     (mesure.date_mesure between '"&debut&"' and '"&fin&"') GROUP BY mesure.id_truc, mesure.date_inscription ORDER BY total_point DESC, mesure.date_inscription"
 
Set RSperf = Server.CreateObject("ADODB.Recordset" )
RSperf.Open strSQL, objdbconnperf, 1
 
if not rsperf.eof then%>
    <%for i=1 to 15%>
    <% Set objtruc=server.CreateObject("ADODB.Connection" )
       objtruc.open "provider=MICROSOFT.JET.OLEDB.4.0;Data Source="&Server.MapPath("data/ma_bdd.mdb" )
       set rs_truc=objtruc.execute("select * from comptes where id="&rsperf("id_truc" ))%>
       <%=i%>- mon bla bla html pour l'enregistrement<br><%
       rs_truc.close
       set rs_truc=nothing
       objtruc.close
       Set objtruc=nothing
 
       rsperf.movenext
       if rsperf.eof then
   exit for
       end if
    next%>
<%else%>
   Classement non établi  
<%end if%>
 
J'ai quand même remplacer une requête SQL Server + 16 requêtes SQL type select sous Access en 2 requêtes + 2 boucles DO.  
 
J'attends vos propositions mais ce qui m'importe le plus ce sont les explications  :hello:  
 
Merci à vous


Message édité par housk le 08-10-2004 à 11:52:31
Reply

Marsh Posté le 08-10-2004 à 11:49:05   

Reply

Marsh Posté le 08-10-2004 à 12:05:00    

vttman2 a écrit :


Access => IIF  :whistle:


[:mlc]
T'es pas sorti si tu comptes vraiment remplacer un gros decode par un iif...[:joce]


Message édité par skeye le 08-10-2004 à 12:05:10

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 08-10-2004 à 13:31:43    

Nan C sûr !

Reply

Marsh Posté le 08-10-2004 à 15:21:39    

housk > Hmmm... En effet, si t'as une requête qui tourne sur SQL Server et l'autre sur Access, c'est pas évident (même si c'est possible)
 
Pourquoi vous utilisez deux bases ?

Reply

Marsh Posté le 08-10-2004 à 15:42:07    

Arjuna a écrit :

housk > Hmmm... En effet, si t'as une requête qui tourne sur SQL Server et l'autre sur Access, c'est pas évident (même si c'est possible)
 
Pourquoi vous utilisez deux bases ?


 
Pour faire simple, tout simplement car au tout début, nous utilisions Access (car livré avec office), et que par la suite nous avons opté pour MSDE quand on a vu que ça pêtait quand le nombre de connexions sur notre site a grimpé ;) Si j'avais le temps et l'autorisation de ma direction, j'aurai tout passé sous MSDE depuis longtemps. Vala.

Reply

Marsh Posté le 08-10-2004 à 21:40:45    

Ha ben ouais.
 
L'éternel problème :
- monsieur, là je peux plus bosser correctement, ça pète de partout, un jour ça va plus jamais marcher.
- on n'a pas d'argent, et au lieu de te plaindre répare ce qui pète !
 
:cry:

Reply

Marsh Posté le 11-10-2004 à 08:55:48    

Arjuna a écrit :

Ha ben ouais.
 
L'éternel problème :
- monsieur, là je peux plus bosser correctement, ça pète de partout, un jour ça va plus jamais marcher.
- on n'a pas d'argent, et au lieu de te plaindre répare ce qui pète !
 
:cry:


 
Ouais, et comme au pays de radin et compagnie, l'informatique c'est aussi facile que 3 macros sous Excel, tu vois le genre ;) allez bonne journée dans la jungle

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed