[SQL]Factorisation de sous-requêtes

Factorisation de sous-requêtes [SQL] - SQL/NoSQL - Programmation

Marsh Posté le 06-07-2010 à 09:44:32    

Bonjour,
 
J'ai une requête qui fait plusieurs fois appel à une même sous-requête. J'aurais aimé savoir s'il était possible de factoriser ses sous-requêtes. J'ai essayé avec CREATE FUNCTION sans succès, car je n'arrive pas à faire un SELECT dans une fonction.
 
Merci par avance :)

Reply

Marsh Posté le 06-07-2010 à 09:44:32   

Reply

Marsh Posté le 06-07-2010 à 09:48:54    

Il va falloir expliquer mieux le problème, là...?


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

Marsh Posté le 06-07-2010 à 10:23:36    

Ok :)
Un exemple court (dans mon problème mes requêtes sont trèèèès longues) :
 

> SELECT `tempo`.`minutes`*60*(SELECT COUNT(*) FROM `chutes` WHERE `chutes`.`id_maladroit`=`tempo`.`id_maladroit`) AS 'temps_de_chute',
         `tempo`.`distance`*(SELECT COUNT(*) FROM `chutes` WHERE `chutes`.`id_maladroit`=`tempo`.`id_maladroit`) AS 'distance_de_chute'
  FROM `tempo`;


Je me retrouve avec 2 sous-requêtes.
Je me suis d'abord demandé s'il était possible de n'appeler qu'une seule fois la sous-requête par enregistrement de tempo(ce serait je pense idéal) :
 

> SELECT (SELECT COUNT(*) FROM `chutes` WHERE `chutes`.`id_maladroit`=`tempo`.`id_maladroit`) AS 'nbchutes',
         `tempo`.`minutes`*60*`nbchutes` AS 'temps_de_chute',
         `tempo`.`distance`*`nbchutes` AS 'distance_de_chute'
  FROM `tempo`;


... Mais ça ne marche pas, car lemoteur SQL ne reconnait pas `nbChutes`; alors je me suis dit d'au moins rendre la requête plus lisible, en factorisant l'appel par une fonction :
 

> CREATE FUNCTION nbChutes (id int(11)) RETURNS int(11)
  RETURN (SELECT COUNT(*) FROM `chutes` WHERE `chutes`.`id_maladroit`=`tempo`.`id_maladroit`);
 
> SELECT `tempo`.`minutes`*60*nbChutes(`tempo`.`id_maladroit`) AS 'temps_de_chute',
         `tempo`.`distance`*nbChutes(`tempo`.`id_maladroit`) AS 'distance_de_chute'
  FROM `tempo`;


Mais bien évidement, il ne m'est pas autorisé de faire un SELECT dans une fonction ...
 
Voilà, j'espère que c'est un peu plus clair

Reply

Marsh Posté le 06-07-2010 à 10:38:50    

Putain c'est quoi cette syntaxe avec toutes ces quotes, c'est illisible.
Je propose:

SELECT t.minutes*60*temp.nbchutes "Temps de chute",
t.distance*temp.nbchutes "Distance de chute"
FROM tempo t JOIN (SELECT id_maladroit, COUNT(*) nbchutes FROM chutes GROUP BY id_maladroit) temp ON t.id_maladroit = temp.id_maladroit;


Sinon pour la fonction, je suppose qu'il manque une étape ou tu affectes le résultat de la requete à une variable, et c'est cette variable que tu dois renvoyer.


Message édité par lasnoufle le 06-07-2010 à 10:40:33

---------------
C'était vraiment très intéressant.
Reply

Marsh Posté le 06-07-2010 à 10:41:03    

quel sgbd? Tu ne peux pas tout simplement faire tes calculs dans le langage appelant, s'il y en a un?
 
Sinon tu peux probablement faire un truc de ce genre-là :
 

Code :
  1. SELECT minutes*60*nbchutes, distance*nbchutes
  2. FROM
  3. SELECT id_maladroit, minutes, distance, count(*) AS nbchutes
  4. FROM tempo
  5.           JOIN chutes ON chutes.id_maladroit = tempo.id_maladroit
  6. GROUP BY id_maladroit, minutes, distance


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

Marsh Posté le 06-07-2010 à 10:59:45    

sgbd = mysql
J'ai pris l'habitude de toujours quoter mes champs et mes tables.
 
Apparemment, la solution se trouve dans les jointures : merci à vous deux, je vais étudier cela avec attention !!

Reply

Marsh Posté le 06-07-2010 à 11:24:02    

- regardes si tu peux pas virer le count(*). En général, on évite de mettre le *,
- regardes si t'as bien mis les index sur les bons champs (regardes avec la fonction EXPLAIN).


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 06-07-2010 à 11:28:14    

rufo a écrit :

- regardes si tu peux pas virer le count(*). En général, on évite de mettre le *,


branlage de nouille.:o


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

Sujets relatifs:

Leave a Replay

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