8
votes

Fonction d'analyse Oracle pour la valeur minimale dans le groupement

Je suis nouveau pour travailler avec des fonctions analytiques. XXX PRE>

Je souhaite le département et l'employé avec un salaire minimum minimum. p>

Les résultats doivent ressembler à: p> xxx pré>

éditer: Voici le SQL que j'ai (mais bien sûr, cela ne fonctionne pas car il souhaite du personnel dans la clause du groupe par la clause): p>

SELECT dept, 
  emp,
  MIN(salary) KEEP (DENSE_RANK FIRST ORDER BY salary)
FROM mytable
GROUP BY dept


0 commentaires

4 Réponses :


3
votes

Vous pouvez utiliser la syntaxe rang () . Par exemple, cette requête vous dira où un employé se classe au sein de leur ministère en ce qui concerne la taille de leur salaire: xxx

vous pouvez alors interroger à partir de là où salaire_rank_within_dept = 1 : xxx


15 commentaires

Parfait! Je ne connaissais pas encore le rang (). Merci.


Je ne connaissais même pas le rang () jusqu'à hier! :)


J'envoie cela pour les raisons que j'ai décrites dans ma propre réponse: je pense que c'est probablement inefficace, et je pense que la requête n'est pas une bonne correspondance à la question exacte posée. Je ne dis pas que cela ne donnera pas la bonne réponse, mais cela n'exprime pas très bien la logique de la question.


@David: assez évident de la réponse Timestamps que vous avez levé ma réponse en vous votant.


Votre réponse, Rexem, n'utilise pas les fonctions analytiques. Comment ai-je "soulevez-le"?


Wow. Vous avez supprimé ma réponse Rexem? Ma réponse complètement différente au tienne? Celui qui a utilisé des fonctions analytiques que les vôtres ne l'ont pas fait? Celui que j'ai mis l'effort pour expliquer pourquoi une fonction analytique min () était probablement meilleure qu'une fonction de rang ()? Avez-vous 15 ans ou trop incompétent pour voir la différence?


Pour le compte rendu, Rexem a édité ma réponse pour dire quelque chose comme "Je ne souleveras pas les idées de concurrents et les descendre". Concurrents? Grandir


Min est une fonction agrégate , nécessitant un groupe par déclaration, sauf si vous utilisez la partition par .


@David: Je ne suis pas celui qui soumet une réponse après La question a déjà été marquée, puis passez à tous les autres parce que le commentaire dans la réponse est 't assez. totalement pathétique .


Ah, vous l'avez modifié à "Je ne souleveras pas les réponses et les compétiteurs Downvote", car ... vous n'avez jamais entendu parler de fonctions analytiques! Inestimable. Merci de vous humilier si complètement, de manière technique et personnelle. Veuillez lire le manuel précis: télécharger.oracle .COM / DOCS / CD / B19306_01 / SERVER.102 / B14200 / ... et merci encore de jouer.


@David: Vous dites donc que Asktom est faux: asktom.oracle.com/pls/asktom/... ;) À la fin, il n'y a qu'une seule fonction min.


Quelle partie de cette posture asktom avez-vous pensé selon vous que min () n'est pas à la fois une fonction globale et une fonction analytique en fonction de la syntaxe? Cette question a été marquée "Oracle" et "Fonctions analytiques", et puisque vous ne savez pas non plus (votre utilisation de citations simples sur un alias de table dans votre réponse augmenterait ORA-00923 une preuve simple de votre inexpérience Oracle) alors Peut-être auriez-vous dû rester en clair. Si votre conflit est que Min () n'est pas une fonction analytique, lisez le manuel et soyez éclairé. Sur une note personnelle, laissez tomber l'ego professionnel et pensez la prochaine fois.


Oh, hilarant: Rexem a édité les balises sur la question initiale de sorte qu'il indique "les fonctions d'agrégat" au lieu des "fonctions analytiques" de Travis. La question elle-même dise "analytique"! Donc, pour soutenir votre ego meurtri rexem, vous êtes prêt à faire ressembler aux gens de ne pas pouvoir mettre les ballots corrects sur la question? Allez-vous éditer la question actuelle de sorte que cela correspond à votre réponse? Stackoverflow.com/revisions/1533240/List


@Rexem: J'ai supprimé la balise PLSQL que vous avez ajoutée (encore) aussi. Je pense que Travis sait ce que PLSQL est, et c'est pourquoi il n'a pas ajouté cela à l'origine et c'est pourquoi il l'a pris après avoir ajouté la première fois. Je pense que vous ne savez pas ce que PL / SQL est, Rexem.


Dudes, si vous voulez avoir une guerre de flamme, obtenez un blog. Je remercie tout le monde de m'aider avec ma requête. Après avoir examiné la solution de David, je l'ai refacturé et l'a marqué comme la réponse parce que je crois que c'est une meilleure réponse. J'exhorte maintenant tout le monde à passer à autre chose.



-1
votes
select e2.dept, e2.emp, e2.salary
from employee e2
where e2.salary = (select min(e1.salary) from employee e1)

1 commentaires

Cela vous donnera un enregistrement - le minimum de la table entière. Vous devez regrouper par le ministère de votre sous-sélection.



10
votes

Je pense que la fonction de rang () n'est pas la voie à suivre avec cela, pour deux raisons.

Premièrement, il est probablement moins efficace qu'une méthode min () - P>

La raison en est que la requête doit conserver une liste ordonnée de tous les salaires par département, car elle analyse les données et le rang sera ensuite attribué ultérieurement en relisant cette liste. Évidemment, en l'absence d'index pouvant être exploités pour cela, vous ne pouvez pas attribuer un rang que le dernier élément de données a été lu et la maintenance de la liste est chère. P>

donc la performance du rang () La fonction dépend du nombre total d'éléments à scanner, et si le nombre est suffisant que le tri sur le disque sur le disque, les performances s'effondrent. P>

Ceci est probablement plus efficace: P>

select dept,
       emp,
       salary
from
       (
       SELECT dept, 
              emp,
              salary,
              Min(salary) Over (Partition By dept) min_salary
       FROM   mytable
       )
where salary = min_salary
/


1 commentaires

Merci David. Après avoir examiné ses avantages, j'ai refactorisé votre solution.



5
votes

Je pense que vous étiez assez proche de votre requête originale. Ce qui suit serait exécuté et correspond à votre cas de test:

SELECT dept, 
  MIN(emp) KEEP(DENSE_RANK FIRST ORDER BY salary, ROWID) AS emp,
  MIN(salary) KEEP (DENSE_RANK FIRST ORDER BY salary, ROWID) AS salary
FROM mytable
GROUP BY dept


2 commentaires

Oui, c'est un bon point sur les multiples enregistrements. La ou les méthodes min () récupéreront tous les doublons ... Soyez plus difficile d'obtenir un seul record pour ceux qui étaient nécessaires.


Excellente élaboration - surtout si l'analyse étant posée est plus préoccupée par la valeur du minimum. Si Identification des attributs du minimum était nécessaire, la préservation des doublons semblerait souhaitable.