Vous n'êtes pas identifié(e).
Pages : 1
Bonjour,
J'ai un problème.
Je voudrai écrire une requête qui donne le MAX d'un COUNT... Comment faire ?
Merci
Hors ligne
Le max du count de quoi exactement ?
Quelque chose comme
SELECT max(toto) FROM (SELECT count(*) AS toto FROM titi GROUP BY tutu) AS tmp ?
Marc.
Hors ligne
Alors en fait j'ai trois tables:
une table "rencontre": avec comme attribut "type de rencontre", "id_rencontre", le reste n'est pas important, ça concerne date et heure et lieux..
une table membre avec un id_membre et pleins d'information sur les différents membres
une table RDV qui lie les deux tables. Ses attributs sont "id_membre" et "id_rencontre". Je voudrai savoir quelle rencontre a attiré le plus de membres, en classant par type. Donc en gros, pour chaque type de rencontre, quelle rencontre a rassembler le plus membres.
Je faisais un truc du genre:
SELECT type, rdv.id_rencontre, COUNT(DISTINCT id_membre)
FROM rdv, rencontre
WHERE rdv.id_rencontre=rencontre.id_rencontre
GROUP BY type, rdv.id_rencontre
HAVING MAX(COUNT);
Mais on ne peut pas mettre ensemble deux fonctions comme MAX et COUNT...
Hors ligne
Donc utilisez la syntaxe que je vous ai donné plus haut… il faut résoudre ça avec une sous-requête.
Par ailleurs, dans la mesure du possible, évitez l'ancienne syntaxe de jointure, et préférez "JOIN", même si dans cette requête cela ne changera rien.
Marc.
Hors ligne
Très bien merci à vous
Hors ligne
Je reviens vers vous pour vous poser une autre question:
voici la requête faite:
SELECT type, EXT.id_rencontre, MAX(compte)
FROM rdv AS EXT NATURAL JOIN rencontre AS OUT, (
SELECT COUNT(id_membre) AS compte
FROM rdv AS dedans
GROUP BY dedans.id_rencontre) AS tmp
GROUP BY EXT.rencontre, type;
J'ai réussi grâce à vous à obtenir le max du COUNT. Mais maintenant il me l'afficher pour chaque id_rencontre alors que ce n'est pas valable. Je m'explique: par exemple pour l'id_rencontre n°3 j'ai 2 id_membre pour le type de rencontre 1. Maintenant j'ai l'id_rencontre n°4 j'ai 3 id_membre pour le type de rencontre 1.
Il m'affiche ceci:
id_rencontre type MAX
3 1 3
4 1 3
Je voudrai bien sur qu'il ne m'affiche que l'id rencontre n°4.
J'ai du mal à trouve le problème qui me parait si simple pourtant.
Désolé ce n'est vraiment pas dans mon habitude de demander trop de chose comme ça.
Dernière modification par adambase (22/12/2016 13:37:40)
Hors ligne
Ça ne correspond pas trop à ce que vous cherchez.
Si on part de l'hypothèse que:
select type, id_rencontre,id_membre
from rencontre
join rdv using (id_rencontre)
vous donne bien la liste des rencontres avec les membres associés et le type,
select type, id_rencontre,count(*) as nb_membre
from rencontre
join rdv using (id_rencontre)
group by type,id_rencontre
Si vous voulez trouver pour chaque type l'id_rencontre ayant ramené le plus de membres:
select distinct on (type) type,id_rencontre,nb_membre
from
(select type, id_rencontre,count(*) as nb_membre
from rencontre
join rdv using (id_rencontre)
group by type,id_rencontre) as tmp
order by type, nb_membre desc
C'est probablement un distinct on que vous cherchiez finalement (https://www.postgresql.org/docs/9.0/sta … elect.html)
Marc.
Hors ligne
c'est parfait, ça marche! merci beaucoup à vous!
Juste qu'est ce que le "desc" à la fin?
et comment marche le DISTINCT ON(type) type?
et comment il prend que les rencontres avec le plus de membres?
encore une fois merci, c'est mes dernières questions je pense et j'espère!
Dernière modification par adambase (22/12/2016 16:23:51)
Hors ligne
«desc» pour trier par ordre descendant.
La requête demande de ne retenir qu'une seule ligne par type, la première ligne trouvée (le distinct on (type)). Le tri final sert à justement s'assurer que les enregistrements arrivent dans l'ordre dans lequel on veut pour que le premier soit le bon: on trie par type, et par nb_membre descendant.
Marc.
Hors ligne
ah d'accord, donc si j'ai bien compris d'abord on compte le nb de membre pour chaque rencontre, puis on les trie par ordre décroissant et on sélectionne la première ligne qui est donc la rencontre ayant attiré le plus de monde?
Mais si par exemple deux rencontres de même type ont attiré autant de membre? une ne sera pas sélectionner non?
Merci encore pour votre aide
Dernière modification par adambase (22/12/2016 16:31:37)
Hors ligne
Oui, ça ne gère pas les ex-aequos
Marc.
Hors ligne
comment les gérer?
Hors ligne
Ça va être beaucoup un peu plus compliqué.
Une des solutions, c'est d'utiliser des window functions (j'essayais de l'éviter, vu que vous êtes débutant et que je ne voulais pas que ça soit trop «brutal» pour un début).
Si on repart de cette requête
select type, id_rencontre,count(*) as nb_membre
from rencontre
join rdv using (id_rencontre)
group by type,id_rencontre
Ce qu'on voudrait, c'est établir un classement des count(*)
select *, rank() over (partition by type order by nb_membre desc) as classement
from (
select type, id_rencontre,count(*) as nb_membre
from rencontre
join rdv using (id_rencontre)
group by type,id_rencontre ) as tmp
Cette requête va nous donner la liste des type,id_rencontre,count(*), et une colonne classement qui est le rang de l'enregistrement pour un type donné, quand on trie par nb_membre décroissant. Si on a des ex-aequos, ils ont le même classement.
De là, si on ne veut que les premiers, ex-aequo:
select type,id_rencontre,nb_membre from
(
select *, rank() over (partition by type order by nb_membre desc) as classement
from (
select type, id_rencontre,count(*) as nb_membre
from rencontre
join rdv using (id_rencontre)
group by type,id_rencontre ) as decompte
) as classements
where classement =1
https://www.postgresql.org/docs/current … indow.html
Dernière modification par Marc Cousin (22/12/2016 17:05:05)
Marc.
Hors ligne
En effet c'est un peu nouveau, je ne connais pas la fonction rank ni partition. Je ne les pas encore vues en cours.
Mais je comprend le principe de cette requête.
D'abord on compte les membres pour chaque rencontre, mais je ne comprend pas comment SQL sait qu'il doit compter "id_membre"...J'ai un peu de mal avec le COUNT(*) à chaque fois.
Puis on trie les rencontre par ordres de nb_membre décroissant
Ensuite on leur attribue des rangs (ça me fait penser a un test statistique non paramétriques...)
et quand le rang est égal à 1, donc la ou les première(s) valeure(s) dans le classement et vu qu'ils est décroissant ce sont les valeurs recherchées.
Pour finir on les affiche.
C'est bien ça?
Si vous pouvez m'expliquer comment marche "rank over" et "partition by", ce serait parfait . Si vous avez le temps bien sur, j'ai déjà bien abusé de votre temps...
Hors ligne
Si possible, lisez la page que j'ai mise à la fin de mon post précédent pour commencer. Elle explique tout ça en détail avec des exemples.
Et exécutez la requête interne (celle que j'ai appelée «classements») pour voir ce qu'elle produit.
Marc.
Hors ligne
Pages : 1