Bonjour,
J'ai en effet oublié le WITH de la CTE en début de requete. J'ai corrigé dans mon post initial.
Bonjour,
J'ai en effet oublié le WITH de la CTE en début de requete. J'ai corrigé dans mon post initial.
Ah, ce n'était que ça ! Désolé, j'aurais dû le voir mais n'étant pas un expert en SQL (bien que j'aurais voulu l'être), j'ignorais même l'existence du mot-clé WITH !
J'ai essayé la commande et je ne trouve pas le même résultat que la première. J'obtiens 268167 (ce sont toujours des secondes, je suppose) au lieu de 456460 secondes (ma première requête pour le total de temps).
Le ORDER BY ne doit-il pas plutôt s'appliquer à la date ?
Par contre, la requête s'exécute instantanément, contrairement à la mienne qui dure environ 45 secondes.
Laquelle ?
Est-ce que la composante horaire de votre datetime est renseignée ? auquel cas il pourrait y avoir de nombreux exæquo, ce qui pourrait expliquer la différence dans le résultat
vous pouvez aussi condenser l'écriture de la requete que j'ai proposée ainsi :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 WITH pa AS ( SELECT SUM(temps_en_sec) duree , MIN(date_et_heure) premierAppel , DENSE_RANK() OVER(ORDER BY MIN(date_et_heure)) AS rang FROM appels GROUP BY numero_sortant ) SELECT SUM(duree) FROM pa WHERE rang > 3000
C'est de cette requête dont je parlais !Oui, toutes les lignes ont le datetime renseigné avec les minutes et les secondes ! Dans le cas où il y aurait des doublons, il devrait normalement y en avoir très peu… Et avec la requête condensée, je tombe sur le même résultat (268167).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 select sum(temps_en_sec) from Appels$ where not (numero_sortant in (select top 3000 numeros.diff_nums from (select distinct numero_sortant as diff_nums from Appels$) as numeros order by date_et_heure));
Dans votre requête, vous utilisez la fonction DENSE_RANK() qui, je suppose, trie les données afin d'obtenir par rang, et dans le OVER(…) vous indiquez avec quoi trier. Cependant, à quoi sert la fonction MIN(…) ? J'ai vu que ça sert à récupérer la plus petite valeur, mais là, elle sert à indiquer à DENSE_RANK() où commencer ?
Oui, mais cette requête contient une erreur :
Vous faites un order by date_et_heure.
Mais votre sous requete ne contient pas la colonne date_et_heure dans sa sélection. C'est donc la valeur de la colonne date_et_heure de la requete principale qui est prise en compte, ce qui n'a aucun sens, et ce qui fausse le résultat de vos calculs.
Pour éviter ce genre de problème difficile a détecter (car en l’occurrence, vous n'avez pas d'erreur dans la requete qui s’exécute parfaitement), vous devriez systématiquement utiliser des alias, (surtout quand une requete contient plusieurs fois la même table).
ainsi, si vous aviez écrit :
Vous auriez eu l'erreur :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 order by numeros.date_et_heure
Nom de colonne non valide*: 'date_et_heure'.
Ah merci, en effet, je n'avais pas vu !! C'est exactement la requête qu'il me fallait !!
Maintenant, si je veux trier en plus par type de numéro, est-ce comme ça que je devrai faire ? (Admettons que je ne veux que les 06 et les 07, et je rappelle que ma table des numéros ne contient pas le premier 0.)
Est-ce correct ??
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 WITH pa AS ( SELECT numero_sortant AS num -- Récupérons aussi les numéros , SUM(temps_en_sec) duree , MIN(date_et_heure) premierAppel , DENSE_RANK() OVER(ORDER BY MIN(date_et_heure)) AS rang FROM Appels$ GROUP BY numero_sortant ) SELECT SUM(duree) FROM pa WHERE rang > 3000 /* Il suffit juste d'ajouter le tri ici, si je comprends bien. */ AND (pa.num like '6%' or pa.num like '7%');
Tout dépend de ce que vous voulez faire exactement :
Si vous voulez la somme des durées d'appel en ne prenant en compte que les numéros en 06 et 07 et sans prendre en compte les 3000 premiers numéros quels qu'il soient, alors oui, c'est bon
Si vous voulez la somme des durées d'appel en ne prenant en compte que les numéros en 06 et 07 et sans prendre en compte les 3000 premiers qui sont en 06 ou 07, alors il faut remonter la condition de filtre dans la sous requete.
C'est exactement ça : la somme des durées d'appel en ne prenant en compte que les numéros en 06 et 07 et sans prendre en compte les 3000 premiers numéros quels qu'il soient.
Merci pour votre précieuse aide, sans quoi je serai parti avec une requête et des résultats faux !! Et en bonus, j'ai une requête parfaitement standard.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager