Requête sur opération select max - SQL/NoSQL - Programmation
Marsh Posté le 28-05-2008 à 16:08:35
TAM136 a écrit : select count(*) classe from my table |
déjà ça c'est n'imp
En fait la tu comptes tous les elements de la table `my table` et tu "aliasses" le résultat en le nomant "classe".
ça équivaut à:
Code :
|
TAM136 a écrit : j'ai fait un select distinct count(*) classe from my table |
ça c'est pas mieux, tu comptes le nombre de résultats "différents", or le count va toujours te remonter la même chose.
TAM136 a écrit : J'ai également essayé la requête select count (classe) from ma table mais le résultat est là encore inchangé et en outre, le résultat apparaît dans une colonne Expr1000. |
là c'était mieux mais pas encore ça car tu comptes toujours le nombre total de ligne de ta table.
La colonne s'appele alors Expr1000 car tu à virer l'alias `classe` et que c'est un nom automatiquement attribué.
Si j'ai tout compris, tu souhaites en fait compter le nombre de classe "unique" que tu as dans la table `my table` sachant qu'une classe peut avoir plusieurs enregistrement dans celle-ci.
Admettons que `my table` ait la structure suivant: ID_CLASSE | COL1 | ...
Et bien il faut en fait que tu fasses:
Code :
|
Marsh Posté le 29-05-2008 à 07:51:10
anapajari a écrit :
|
Merci infiniment.Mon problème est résolu.
Marsh Posté le 02-12-2008 à 15:49:35
Bonjour,
J'ai besoin d’une explication concernant un problème que je pense avoir résolu avec de la réflexion mais aussi du hasard. Je m’explique. Je souhaite compter le nombre de biens (chaises, tables..) qui se trouvent dans chacune des classes ou salles.
J'ai donc exécuté la requête suivante
Code :
|
Ici nom colonne pour le type de bien
my table est la table contenant cette colonne
La classe ou la salle appartient à une autre table
La requête fonctionne sauf que le nom de colonne représentant le type de bien ne me plaît absolument pas. J’ai donc cherché à lui attribuer un alias. Je précise que je ne suis pas administrateur et que je n'ai pas la possibilité de changer le nom de colonne dans la base de données ce nom. De même j'ai mis un alias à classe: numerodeclasse.
Après exécution de la requête, j'obtiens un truc du genre
Nom colonne Numerodesalle
80 300
90 300A
Alors que je voudrais
Nb de biens Salle
80 300
90 300A
J'ai essayé afin "d'aliasser mon nom de colonne" mais à chaque fois j'ai un message d'erreur
Code :
|
syntaxe incorrectevers alias
Code :
|
Ici sans les parenthèses mais avec le même message
J'ai finalement "aliassé» mon nom de colonne de la façon suivante:
Code :
|
La requête fonctionne et me permet d’aboutir au résultat ci dessus mais je ne comprends pas comment nbdebiens est reconnu.
Si quelqu'un peut me fournir une explication, il est le bienvenu.Merci d'avance.
Marsh Posté le 02-12-2008 à 15:58:03
Franchement, et ce n'est que mon avis, évite les count (*)
Tu n'en as pas besoin, tu sais sur quelle colonne faire ton aggrégat
Je n'ai pas la definition de table mais un truc du genre me semble pas mal :
select id_salle as [Numero de salle], count(distinct id_bien) as [Nb de biens] from 'matableamoilamienne' group by id_salle
Au moins, tu vois de suite quelle colonne tu aliasses, et tu gères bien tes regroupements
Marsh Posté le 03-12-2008 à 07:44:45
Merci, je vais regarder ça.Pour l'utilisation de count, je ne suis qu'un débutant et donc j'aurai du mal à contre argumenter.
Marsh Posté le 05-12-2008 à 13:16:06
TAM136 a écrit : Merci, je vais regarder ça.Pour l'utilisation de count, je ne suis qu'un débutant et donc j'aurai du mal à contre argumenter. |
Finalement, je dois bien avouer que je n'y arrive pas avec ton instruction.Je ne sais pas ce qu représentent les id, ici: clé primaire, clé de liaison..?Effectivement, je n'ai pas donné la structure des tables.Le projet est confidentiel et je sais qu'avec le peu d'éléments fournis,mon explication n'est pas nécessairement claire.En tout cas comme je l'ai dit, je pense y avoir réussi avec ma requête mais sans vraiment la comprendre.Je suis vraiment un débutant.
Merci
Marsh Posté le 05-12-2008 à 14:36:15
Je veux bien que ce soit confidentiel, mais bon...une table c'est quand même pas le bout du monde, change les champs si tu le souhaites.
On s'en tape un peu de la clef primaire ou étrangère si tu ne travailles que sur une seule table (c'est le cas au moins ?).
C'est quand même une requete super simple, si tu ne maîtrises pas cela tu vas galérer pour la suite de ton projet confidentiel.
Admettons un truc que ta table soit du genre
Nom de table : MATABLE
Champs : id_salle numero de salle
id_bien code de l'objet
Pour connaitre le nombre d'objets différents par salle tu fais :
select id_salle as [Numero de salle], count(distinct id_bien) as [Nb de biens] from MATABLE group by id_salle
(selection le numero de salle et le nombre de biens différents stockés dans la table MATABLE par numero de salle)
Marsh Posté le 08-12-2008 à 07:48:56
chapi a écrit : Je veux bien que ce soit confidentiel, mais bon...une table c'est quand même pas le bout du monde, change les champs si tu le souhaites. |
Je vais essayer de mieux reformuler mes propos en changenat les noms quand j'aurai un peu de temps
chapi a écrit : |
Je travaille sur deux tables.Comme je l'ai dit dans mon post, la classe ou la salle appartient à une autre table.
Marsh Posté le 10-12-2008 à 13:04:09
TAM136 a écrit : |
Finalement
select count(*) as nbdebiens, salle numerodesalle
from my table
est équivalent à
select count(*)numerodesalle
from my table
Mais par contre,évidemment,on n'a plus qu'une seule colonne après le lancement de la requête.
Marsh Posté le 10-12-2008 à 13:40:39
Mais....
Là il faut que tu apprennes les bases du sql.
A partir du moment où tu fais un count(*) sur une table, peu importe ce que tu mets comme champs (hors agregats) derrière, tu auras le même resultat puisque tu comptes le nombre de lignes de ta table....rien d'autre.
Là, tu sais à un instant t combien tu as de lignes dans matable. Super. C'est ça la finalité ?
Arrête avec tes count(*). Fais des count sur un champs donné, et travaille avec des group by
Marsh Posté le 11-12-2008 à 07:49:48
chapi a écrit : Mais.... |
Inutile de d'emporter.J'ai fait un truc du genre
Code :
|
ou encore
Code :
|
qui est bien équivalent à
Code :
|
Marsh Posté le 11-12-2008 à 09:35:02
TAM136 a écrit :
|
Arrête avec tes count(*).
Tes group by tels que, ne servent à rien.
Tu ne sais toujours pas combien tu as de bien par salle (enfin si, si tu indiques à chaque fois sur quelle salle tu fais ta recherche)
Marsh Posté le 12-12-2008 à 07:47:53
chapi a écrit : |
La requête suivante m'indique le nombre de biens qu'il y a dans chaque salle et je n'ai évidemment pas à indiquer le n° de salle.C'était juste pour l'exemple.
Code :
|
Bon, pour ce qui est des count(*), j'avoue ne pas avoir tout compris mais en tout cas, j'ai vérifié;la requête que je viens de poster fonctionne.
Marsh Posté le 12-12-2008 à 09:53:11
Oui comme cela, ça fonctionne.
Néanmoins, je te conseille, perso, juste d'éviter les count(*) et de faire tes aggrégats directement sur les champs que tu cherches à calculer. Maintenant, comme tu as fait, ça passe aussi...
Marsh Posté le 12-12-2008 à 14:30:59
>chapi, En ce qui concerne Oracle, et la plupart des SGBD modernes, count(*) ou count(1) ou count(mycolumn) sont absolument équivalents. Tant qu'il n'y a pas de distinct bien sûr.
Marsh Posté le 12-12-2008 à 15:02:20
Nous sommes d'accord mais si tu relis le début de la discussion. Mais c'est justement parce qu'il va avoir besoin tôt ou tard de count (distinct... que je pense AMHA qu'il est préférable de commencer l'aggrégat sur un champ.
Mais ce n'est que mon avis
Marsh Posté le 12-12-2008 à 16:29:23
chapi a écrit : Nous sommes d'accord mais si tu relis le début de la discussion. Mais c'est justement parce qu'il va avoir besoin tôt ou tard de count (distinct... que je pense AMHA qu'il est préférable de commencer l'aggrégat sur un champ. |
Mais j'ai déjà utilisé un count distinct:
Code :
|
ou encore
Code :
|
Ce que je ne comprends pas, c'est tes propos sur l'agrégat sur le champ.Par agrégat, tu parles je pense d'un Group by. De toute façon, si je ne mets de Group by, j'ai le message d'erreur suivant:
Code :
|
Là,c'est logique: si au rez-de-chaussée, on a 20 salles,salle 1,2,....20, je vais regrouper les 20 lignes qui contiennet le champ "Rez-de-chaussée".Ou alors, je n'ai effectivement pas compris ce que tu veux me dire.
Marsh Posté le 15-12-2008 à 16:53:03
Bon si j'ai bien compris, tu as une table décrivant les matériels présents par salle.
Une salle semble être identifiée par son numéro et son niveau (deux salles peuvent avoir le même numéro dans 2 niveaux différents)
Si tu veux le nombre de salles par niveau
select count(distinct salle) ,niveau
from matable
group by niveau
Si tu veux le nombre de salles en tout, il faut faire une concaténation sur la clé (|| en SQL92) ou une sous-requête
select count(distinct salle||niveau)
from matable
version sous requete
select sum(nb) from
(select count(distinct salle) as nb,niveau
from matable
group by niveau)
Marsh Posté le 31-12-2008 à 09:38:34
Bonjour à tous,
Merci à tous ceux qui se sont penchés sur mes problèmes.Je suis à nouveau en difficulté.Je cherche à connaître le bien qui coûte le plus cher (dont le prix est le plus élevé).Les biens appartiennent disons à la table 1 et le prix à la table 2.
Si j'exécute la requête ci-dessous,j'obtiens seulement le prix:
Code :
|
Je dois donc faire une jointure entre les 2 tables,si ne me trompe pas.J'ai donc exécuté la requête ci-dessous:
Code :
|
mais celle-ci me retourne chaque bien le plus cher.
Exemple:
Salle Bien Prix
300 Chaise 50
300A Chaise 60
300B Tableau 300
300C Tableau 400
La requête me retourne
Bien Prix
Chaise 60
Tableau 400
Or je voudrais
Bien Prix
Tableau 400
Bien sûr en triant,j'obtiens le prix le bien qui coûte le plus cher.Mais je voudrais le faire de façon directe de sorte que la requête me retourne bien une seule ligne.
Merci d'avance, bon réveillon et bonne année par avance.
Marsh Posté le 31-12-2008 à 12:47:44
Salut,
Pas évident de se faire une idée de la structure de ta base avec le peu d'infos que tu donnes...
Si ta première requête :
select max(prix) "prix d'achat le plus élevé"
from table 1
fonctionne, il faudrait que tu donnes ce qui relie un prix à un bien.
J'imagine que tu as une table BIEN, avec des identifiants, et une table PRIX avec des identifiants, par contre je ne vois pas ce qui justifie le fait ne pas mettre le prix dans la table BIEN, à moins que le prix ne dépende de la salle, ou d'autres paramètres que tu ne donnes pas.
Si on part de ton énoncé, on peut penser que tu as une liaison 1-1 entre PRIX et BIEN, du coup c'est assez simple :
tu récupère l'Id_Prix qui correspond à ton MAX(Prix), en faisant :
SELECT P1.Id, P1.Prix
FROM PRIX P1
INNER JOIN
(
SELECT MAX(P2.Prix) AS PR2
FROM PRIX P2
) DRV ON DRV.PR2 = P1.Prix
si tu as plusieurs Id au même prix, c'est que ton modèle est vraiment pas bon, mais tu peux t'en sortir en récupérant soit le MIN soit le MAX Id :
SELECT MIN(P1.Id), P1.Prix
FROM PRIX P1
INNER JOIN
(
SELECT MAX(P2.Prix) AS PR2
FROM PRIX P2
) DRV ON DRV.PR2 = P1.Prix
GROUP BY P1.Prix
Ensuite, tu récupère le bien qui est lié à cet Id
Avec cette requête, on a isolé l'Id du prix le plus élevé. Je ne peux pas aller plus loin sans en savoir un peu plus sur la relation PRIX-BIEN.
Bon courage,
Marsh Posté le 31-12-2008 à 13:33:45
Tibar a écrit : Salut, |
Merci,
Je vais regarder ça de près.Je vais essayer de donner plus d'infos si j'ai un souci. Pour ce qui est du fait que le prix n'appartient pas à la même table que les biens,là je n'y suis pour rien.Je ne suis pas le créateur de la base.C'est une boîte qui la créée selon nos besoins mais là où je bosse, il n'y a personne qui maîtrise le SQL.On a donc "fait confiance" en partie d'autant plus que le logiciel peut être exploité sans faire du SQL mais c'est plus fastidieux:exportation sur Excel où il faut utiliser des formules alambiquées et/ou des macros VBA d'une page alors qu'avec SQL, 3 lignes de code suffisent et encore je ne suis pas sûr qu'Excel fasse tout ce qu'on veut!!!Dans tous les cas, je ne tenterai pas une manoeuvre qui risquerait de remettre en cause l'intégrité de la base.
Une fois,nos attentes parfaitement identifiées,nous reprendrons contact avec la boîte.Je sais,ça peut paraître étrange mais avec le temps,de nouvelles attentes et de nouveaux besoins apparaissent.Au départ,on ne savait pas toutes les infos dont nous aurions besoin.Désolé, je ne donne pas trop de détails par confidentialité et afin que la boîte ne soit pas identifiée.
Marsh Posté le 31-12-2008 à 13:51:18
Salut,
Pas de problème... Les évolutions de besoin, ça arrive assez souvent quand même. Essaie quand même peut-être de faire une petite analyse de ton côté afin de savoir si le modèle correspond vraiment à tes attentes et est évolutif, parce que les boites noires desquelles tu ne peux rien sortir sans faire appel au concepteur, c'est vite lassant...
Une base de données, c'est fait pour vivre, pas pour servir de gros fichier dans lequel on met tout en vrac, et pour bien vivre, il faut qu'elle soit bien conçue...
Bon courage,
Marsh Posté le 06-01-2009 à 08:29:45
Salut,
Merci de t'être penché sur mon problème mais j'ai une erreur au niveau du mot clé DRV. Pour info, je suis sous MySQL.Pour revenir sur ta question concernant le lien entre le bien et le prix, je dois t'avouer ne pas la comprendre.Il y a évidement un lien entre la table contenant le biens et la table contenant le prix ou autrement dit une clé de liaison mais un lien entre le prix et le bien, là, je ne saisis pas trop.
Concernant également ta phrase: "si tu as plusieurs Id au même prix", là non plus je ne comprends pas.Si tu te demlandes s'il peut y a avoir plusieurs biens au même prix, la réponse est bien oui avec par exemple:
Salle Bien Prix
300 Chaise 50
300A Chaise 50
300B Tableau 300
300C Tableau 300
Concernant les infos qui te manquent, je suis en train de voir avec la boîte.
Merci
Marsh Posté le 06-01-2009 à 13:24:12
Salut,
Ayant juste accès en lecture à la base MySQL que je connais, j'ai testé ça :
SELECT P1.address_id, P1.zip_code
FROM ADDRESS P1
INNER JOIN (
SELECT MAX( P2.zip_code ) AS PR2
FROM ADDRESS P2
)DRV ON DRV.PR2 = P1.zip_code
c'est à peu près la même chose, en remplaçant le prix par le code postal, et je n'ai pas d'erreur de syntaxe.
Pour info, DRV n'est pas à proprement parler un mot clé, mais c'est le nommage que j'ai utilisé pour signaler que la requête entre parenthèse était une requête dérivée.
Si tu as une relation entre le prix et le bien, tu dois pouvoir retrouver ensuite le bien qui a le prix le plus élevé.
En fait, ma deuxième requête (celle avec le MIN), permet de ne sortir qu'un id_bien si tu as plusieurs biens au même prix.
L'exemple des prix que tu m'as donné me conforte dans l'idée que le modèle n'est peut être pas idéal. En effet, une chaise, qu'elle soit dans la salle X ou Y, coute le même prix. A la rigueur, si tu as plusieurs fournisseurs, on pourrait imaginer de ne pas avoir le prix dans la même table que le produit, avec une structure du style :
PRODUIT
id_produit
libelle
...
FOURNISSEUR
id_fournisseur
nom
...
PROPOSER
id_produit
id_fournisseur
prix
...
dans ce cas, le prix d'un produit dépend d'un fournisseur... Après le fait que ce ne soit pas dans la même table n'est pas génant en soit...
Si tu pouvais me donner l'erreur que te sort MySQL, je regarderai plus en détail, sinon pour "débuger", tu peux essayer de lancer en premier uniquement la requête entre parenthèse, à savoir (en adaptant à tes noms de champ bien sur) :
SELECT MAX( P2.zip_code ) AS PR2
FROM ADDRESS P2
Si ça passe, c'est qu'une table a été mal aliasée...
Bon courage,
Marsh Posté le 07-01-2009 à 13:53:40
Salut,
Je vais essayer d'être plus clair.
J'ai 3 tables:
Table1
id_fournisseur
nom
Table2
id-produit
libelle
Table3
prix
Le prix et le produit ne sont donc pas dans la même table.La table 1 ne sert à rien pour la requête en cause, en tout cas.Le message d'erreur est le suivant:
Error Number=-2147217900
Native Error Number=170
Dans ta requête suivante:
SELECT MIN(P1.Id), P1.Prix
FROM PRIX P1
INNER JOIN
(
SELECT MAX(P2.Prix) AS PR2
FROM PRIX P2
) DRV ON DRV.PR2 = P1.Prix
GROUP BY P1.Prix
Tu utilises une seule table ou je n'ai pas compris.J'avoue que je m'y perds un peu.
Merci
Marsh Posté le 07-01-2009 à 17:47:50
Salut,
En effet, je n'utilise qu'une seule table... Comme je te disais dans ma première réponse, elle permet de sortir l'id du prix le plus élevé, après tu peux le joindre avec la table qui relie le Prix au Produit et ainsi obtenir le produit qui a le prix le plus élevé...
Par contre si la requête ne fonctionne pas, ça ne va pas t'avancer beaucoup...
En tout cas, c'est la seule méthode que je connaisse pour répondre à ta question, et elle fonctionne sur MySQL (une autre personne a à peu près le même problème dans un post du forum, et c'est passé)...
Bon courage,
Marsh Posté le 28-05-2008 à 15:57:04
Bonjour à tous
J'ai un nouveau probleme qui me fait tourner en rond et qui risque de me rendre fou alors que la question est très simple. Je veux compter le nombre de classes.
J'éxécute la requête suivante:
Le hic c'est que le résultat retourné est ahurissant car je crois comprendre que la requête fait le total de tous les champs où apparaît une salle,soit
salle 300 table
salle 300 table
salle 300 table
salle 300 chaise
salle 300A ordinateur
salle 300A projecteur
.....
ce qui donne 6 et non 2
Alors,j'ai fait un
Le résultat est inchangé
J'ai également essayé la requête select count (classe) from ma table mais le résultat est là encore inchangé et en outre, le résultat apparaît dans une colonne Expr1000.
Résultat de la reqête
Expr1000
Résultat
Pour essayer de comprendre mon problème,j'ai exécuté la requête suivante:
sans préciser la colonne.J'obtiens de nouveau
Résultat de la reqête
Expr1000
Résultat
J'en déduis donc que le résultat obtenus correspond au nombre d'enregistrements mais je reste bloqué comme indiqué en début de message.
Merci par avance pour votre collaboration.
Message édité par TAM136 le 31-12-2008 à 09:42:01