2010-03-12 16 views
4

Je les tableaux ci-dessous dans une base de données (je ne détaillons les attributs importants):Quel est le problème avec cette requête de base de données?

Person(ssn,countryofbirth) 
Parents(ssn,fatherbirthcountry) 
Employment(ssn, companyID) 
Company(companyID, name) 

Ma tâche est la suivante: fatherbirthcountry donnée comme entrée, sortie le nom des sociétés où les personnes travaillent dont countryofbirth correspondre à la entrée fatherbirthcountry.

Je fais semblant que le fatherbirthcountry est le Mexique et faire ceci:

SELECT name 
FROM Company 
WHERE companyid = (SELECT companyid 
        FROM Employment 
        WHERE ssn = (SELECT ssn 
           FROM Person 
           WHERE countryofbirth = 'Mexico'); 

mais il me donne une erreur:

>Scalar subquery is only allowed to return a single row. 

suis-je complètement hors piste? Quelqu'un peut-il aider s'il vous plaît?

+1

Quand je tapais ma réponse, je reçu un message « 6 réponses nouvelles ont été publiées Charger nouveau. réponses?" (dans les 2 minutes) ... – Amsakanna

+0

Oui c'est pour le derby – VeePee

+0

Quelle que soit l'approche que vous suiviez, vous voudrez probablement 'SELECT DISTINCT name ...'. – pilcrow

Répondre

6

Le problème est que vos sous-requêtes retournent plusieurs résultats, vous devez donc utiliser where in contre =.

Remplacez where ssn = par where ssn in et where companyid = par where companyid in.

+0

merci beaucoup Monsieur. – VeePee

0

Essayez d'utiliser IN au lieu de =

Lorsque vous écrivez:

select a from T where a = (select....) 

La sous-requête doit renvoyer une valeur unique. Dans le cas où il renvoie plusieurs valeurs, vous obtenez votre erreur. Pour résoudre ce problème, nous utilisons l'opérateur IN qui permet à la sous-requête de renvoyer un ensemble de valeurs (> = 0) et votre condition where réussit si a est égal à l'une de ces valeurs.

select a from T where a IN (select....) 
1

Vous devez utiliser In dans la condition where car le (SELECT ssn FROM Person WHERE countryofbirth = 'Mexico'); peut renvoyer plusieurs valeurs ssn.

SELECT name 
FROM Company 
WHERE companyid = (SELECT companyid 
        FROM Employment 
        WHERE ssn IN (SELECT ssn 
           FROM Person 
           WHERE countryofbirth = 'Mexico'); 
2

essayez d'utiliser le mot clé IN pas '='.

essayez de changer votre requête à ce

SELECT nom de la compagnie OU CompanyID IN (SELECT CompanyID
de l'emploi OÙ Ssn IN (SELECT ssn FROM Personne OU countryofbirth = 'Mexique');

0

Voir si cela fonctionne

SELECT c.Name FROM PERSON p
LEFT JOIN Employment e ON p.ssn=e.ssn LEFT JOIN Company c ON e.CompanyID=c.CompanyID WHERE p.countryofbirth=

0

L'erreur est due au fait que l'une des deux sous-requêtes renvoie plusieurs lignes. Je pense qu'il est probable que vous avez plusieurs personnes nées au Mexique par exemple.

Select Name 
From Companies 
Where Exists(
      Select 1 
      From Employment 
       Join Person 
        On Person.SSN = Employment.SSN 
       Join Parents 
        On Parents.SSN = Person.SSN 
      Where Parents.FatherBirthCountry = Person.CountryOfBirth 
       And Parents.FatherBirthCountry = @InputParam 
       And Employment.CompanyId = Companies.CompanyId 
      ) 
2

Utilisation:

SELECT c.name 
    FROM COMPANY c 
    JOIN EMPLOYMENT e ON e.companyid = c.companyid 
    JOIN PERSON p ON p.ssn = e.ssn 
       AND p.countryofbirth = 'Mexico' 
+0

En réalité, les sous-requêtes et les jointures utilisent les mêmes plans de requête sur SQL Server. Essaye le. –

+1

il peut ne pas fonctionner mieux, mais à mon avis, il est un peu plus facile à lire – Dexter

+0

@David B: Je vais tester demain, mais la question semble se rapporter à Derby - pas de SQL Server. –

0

utiliser Idéalement, la réponse de OMG Ponies en utilisant JOIN s.
Mais si vous ne l'aimez pas JOIN s pour une raison quelconque, TOP 1 devrait faire l'affaire pour vous:

SELECT name 
FROM Company 
WHERE companyid =(SELECT TOP 1 companyid 
        FROM Employment 
        WHERE ssn = (SELECT TOP 1 ssn 
            FROM Person 
            WHERE countryofbirth = 'Mexico');