2015-12-05 1 views
3

Il s'agit de la base de données, clé primaire en gras.Pourquoi est-il plus difficile de rechercher des entités avec plus de chaque vs moins que certains?

  • works (person_name, company_name, salary)

Supposons que nous ayons ce problème:

Trouver les noms de tous les employés qui gagnent plus que tous les employés de la petite banque Corporation.

solution proposée:

Nous ne pouvons pas calculer facilement l'ensemble des employés qui gagnent plus que tous les employés de la petite Bank Corporation, mais nous pouvons calculer l'ensemble des employés qui gagnent moins de certains employés de la petite banque Corporation. Nous soustrayons cet ensemble de l'ensemble de tous les employés. Notez le moins ou égal et que nous supprimons les enregistrements avec le même nom.

temp ← ∏person_name(σp(works⨯ρd(works))) 

où p est

works.person_name ≠ d.person_name ∧ 
works.salary ≤ d.salary ∧ 
d.company_name = "Small Bank Corporation" 

la réponse est:

∏person_name(works) − temp 

Pourquoi ne peut-on calculer facilement l'ensemble des personnes qui gagnent plus que tous les employés de la petite banque Société ? Et pourquoi pouvons-nous calculer facilement l'ensemble des personnes qui gagnent le moins? Je ne comprends pas ça. Que fait works.salary < = d.salaire exactement faire? Fait-il une boucle pour chaque entité works.salaire à travers toutes les entités d.salary et regarde si elle est < = pour TOUTES les entités d.salary?

+1

Si vous recherchez une solution dans SQL, il existe plusieurs façons d'exprimer cette requête. –

+0

Qui a proposé la solution? Ou demandez-vous pourquoi votre solution n'est pas facile? –

+0

@EmacsUser La question n'est pas de savoir quelle est la requête, la question est de savoir pourquoi deux requêtes sont si similaires dans un sens (signification) si différentes dans une autre (expression algebra/sql). – philipxy

Répondre

2

La requête peut être exprimé assez facilement comme ceci:

select person_name 
from works 
where salary > (
    select max(salary) 
    from works 
    where company_name = 'Small Bank Corporation') 
1

Nous ne pouvons pas calculer facilement l'ensemble des employés qui gagnent plus de tous les employés de la petite Bank Corporation, mais nous pouvons calculer l'ensemble des employés qui gagnent moins que certains employés de la petite banque Corporation.

Ce ne sont pas les inégalités qui font la différence. (Vous pouvez voir cela en les changeant simplement dans votre σ.) C'est le POUR TOUS/TOUS vs POUR CERTAINS.

Un prédicat est un vrai-ou-faux remplir-le- (nommé-) des espaces).

-- person [W.P] works for company [W.C] for salary [W.S] 
W (W.P,W.C,W.S) 

Notez que le nom plus ses attributs est une version abrégée du prédicat. Nous appelons le prédicat d'une variable de relation, constante ou expression, son signifiant.

Supposons que les expressions de relation e & f contiennent les lignes qui créent des expressions de prédicat E & F true (respectivement). Les opérateurs d'algèbre ont été conçus de telle sorte que:

R contient les lignes satisfaisant R (R.X, ...)
ρS(ewith attributes R.X) maintient les lignes satisfaisant E avec RX remplacés par SX
e⨯f contient les lignes satisfaisant E ET F
e-f maintient les lignes satisfaisant E ET NON F
eUf contient les lignes satisfaisant E OU F
σcondition(e) maintient les lignes satisfaisant E ET état
πA(e) détient les lignes satisfaisant pour QUELQUES tous les attributs, mais un: E

Il se trouve que pour chaque petit changement par rapport il y a un petit changement de sens . Notez que la liste n'inclut pas l'expression ~(e) ("complement") qui contient des lignes où NOT E, c'est-à-dire les lignes qui ne sont pas dans e. Parce que (en général) c'est beaucoup de lignes et impraticable pour calculer. Mais il s'avère que si nous ne voulons jamais que ces lignes soient un résultat de requête (et nous ne le faisons généralement pas), nous pouvons réécrire en utilisant d'autres opérateurs. POUR TOUS A: E signifie PAS POUR QUELQUE A: NON E. Donc, les requêtes impliquant FOR ALL sont compliquées et nous ne pouvons pas (en général) avoir FORALL à l'extérieur. Le original signifiant n'est pas compliqué, mais nous devons le réorganiser en un phrasé complexe qui est calculé par une expression de relation complexe. Donc la réponse est, il arrive que la relation où POUR QUELQUES A: E est simple à calculer et à visualiser, mais la relation où FOR ALL A: E utilise des appels compliqués d'opérateurs peu coûteux pour calculer à peu de frais et n'est pas un réarrangement humain évident de e.

(Il existe différents cas particuliers d'utilisation de FOR ALL qui se traduisent directement par des appels simples de divers opérateurs de "division" .Mais alors les cas spéciaux n'ont pas de signification simple Il s'avère qu'il est plus simple d'exprimer FOR ALL en utilisant les opérateurs de sous-ensemble de relation.)

(Voir mes réponses & leurs questions here re prédicats & algèbre et here re sql.)

Qu'est-ce que works.salary < = d.salary exactement? Fait-il une boucle pour chaque entité works.salary à travers toutes les entités d.salary et regarde si est < = pour TOUTES les entités d.salary?

Il apparaît dans un appel σ (sélection/restriction). L'appel sort les lignes qui rendent la valeur de la relation d'argument vraie et qui rendent la condition (un prédicat) vraie. C'est-à-dire les lignes qui rendent l'AND (conjonction) des deux prédicats vraie. C'est à dire les roews dans son entrée qui rendent la condition vraie. Tout ce qu'il a à voir avec le résultat global, c'est qu'il calcule quelque chose en cours de route.

Vous pouvez traduire votre requête en langage naturel. Bien que la façon dont vous a écrit c'est par (informellement) traduire si du langage naturel. Cela va s'avérer pour parler d'un maximum.Par exemple, température est les lignes qui satisfont:

-- temp ← ∏works.person_name(σp(works⨯ρd(works))) 
FOR SOME works.company_name, works.salary, 
    d.person_name, d.company_name, d.salary: 
     person [works.person_name] works for company [works.company_name] 
      for salary [works.salary] 
    AND person [d.person_name] works for company [d.company_name] 
      for salary [d.salary] 
    AND [works.salary] <= [d.salary] 
    AND ... 

C'est les lignes où personne [works.person_name] travaille pour la société [works.company_name] pour le salaire [works.salary] et personne [d.person_name] travaille pour la société [ d.compagnie_name] pour un salaire [d.salary] ET [works.salary] < = [d.salary] ET ..., pour certaines valeurs pour les attributs autres que works.person_name. Il s'agit donc d'une liste de personnes où il existe une autre personne (≠) avec un salaire au moins aussi élevé à la Small Bank Corporation. (Votre requête serait plus simple si vous ignoriez les noms de personnes et que vous demandiez simplement des paires de personnes dont l'ouvrier a un salaire inférieur à celui de la personne D. Si leur salaire n'est pas égal au vôtre, alors vous n'êtes pas