2010-10-03 10 views
6

Comment représenter une sous-requête en relation algèbre? Est-ce que je mets le nouveau select sous la condition de sélection précédente?Représenter une sous-requête en algèbre relationnelle

SELECT number 
FROM collection 
WHERE number = (SELECT anotherNumber FROM anotherStack); 
+0

Une sous-requête corrélée? Pouvez-vous donner un exemple SQL pour lequel vous voulez l'AR? –

+0

Edité la requête que je voudrais l'AE pour – AnEventHorizon

Répondre

6

Vous pouvez simplement le réécrire comme join.

Je ne suis pas sûr de la façon dont la syntaxe que j'ai apprise pour l'algèbre relationnelle est très utilisée en mots.

  1. Prendre une projection de anotherNumber de anotherStack
  2. renommer anotherNumber à partir du résultat de l'étape 1 en tant que number
  3. jointure naturelle du résultat de l'étape 2 sur collection
  4. Prenez une projection finale du number à partir du résultat de l'étape 3
+2

Un * pourrait * réécrire cela comme une jointure :) – onedaywhen

1

La réponse dépend des opérateurs que votre algèbre comprend. Un opérateur de semi-jointure serait très utile ici.

Si l'attribut commun était nommé number dans les deux relations, il s'agirait d'une semi-jointure suivie d'une projection de number. En supposant un opérateur ETM-join nommé MATCHING, selon Tutorial D:

(collection MATCHING anotherStack) { number } 

Comme affiché, l'attribut doit être renommé premier:

(collection MATCHING (anotherStack RENAME { anotherNumber AS number }) { number } 

Si Standard SQL (le SQL-92) JOIN peut être considéré , en gros, un opérateur relationnel alors il est vrai que SQL n'a pas de semi-jointure. Cependant, il a plusieurs prédicats de comparaison qui peuvent être utilisés pour écrire un opérateur de semi-jointure, par ex. MATCH:

SELECT number 
    FROM collection 
WHERE MATCH (
       SELECT * 
       FROM collection 
       WHERE collection.number = anotherNumber.anotherStack 
      ); 

Cependant, MATCH n'est pas largement pris en charge dans la vie réelle des produits SQL, donc pourquoi une semi-jointure est généralement écrit en utilisant IN (subquery) ou EXISTS (subquery) (et je soupçonne que c'est pourquoi vous nom coché la case « sous-requête » dans votre question à savoir le terme semi-jointure n'est pas bien connu parmi les praticiens SQL).


Une autre approche consisterait à utiliser un opérateur de croisement si disponible.

Quelque chose comme (pseudo-code):

(collection project number) 
intersect 
((anotherStack rename anotherNumber as number) project number) 

Dans SQL:

SELECT number 
    FROM collection 
INTERSECT 
SELECT anotherNumber 
    FROM anotherStack; 

Ceci est très bien pris en charge dans la vie réelle (SQL Server, Oracle, PostgreSQL, etc, mais notamment pas MySQL).

+1

Vous devriez être un peu plus précis dans votre choix de mots.Si MATCH peut être utilisé dans une clause WHERE (de la manière que vous avez décrite), alors cet opérateur doit retourner un booléen, et alors MATCH ne peut pas être "un opérateur SEMIJOIN", comme vous le prétendez. Un opérateur SEMIJOIN renvoie une relation. –

+0

@ErwinSmout: vous avez un point. L'utilisation du terme "opérateur relationnel" dans le contexte de SQL n'est jamais strictement correcte. Mais il est vrai que j'ai utilisé le terme opérateur trop librement ici. J'ai essayé de le réécrire, mais n'hésitez pas à le modifier pour votre propre satisfaction. – onedaywhen

+1

Si vous voyez à quel point SQL et RA sont vraiment adaptés, il est étonnant que SQL puisse toujours prétendre être une implémentation pour RA, non? Ce qui m'étonne aussi, c'est qu'il semble y avoir beaucoup de gens qui veulent savoir comment réécrire SQL en RA. J'aurais pensé que si SQL est le langage pour la mise en œuvre (/ solution/...), alors RA serait en quelque sorte le langage de la spécification ... Et on a généralement la spécification avant qu'on ait la mise en œuvre ... Ou Ça me manque d'avoir changé pendant mes 5 années passées sur Mars? –

Questions connexes