【问题标题】:What is wrong with this database query?这个数据库查询有什么问题?
【发布时间】:2010-03-12 05:11:57
【问题描述】:

我在数据库中有以下表格(我只会列出重要的属性):

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

我的任务是这样的:给定输入的父亲出生国家,输出与输入的父亲出生国家相匹配的人员所在公司的名称。

我假设父亲出生国是墨西哥,然后这样做:

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

但它给了我一个错误:

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

我完全偏离轨道了吗?有人可以帮忙吗?

【问题讨论】:

  • 当我输入答案时,我收到一条消息“已发布 6 个新答案。加载新答案?” (2分钟内)...
  • 无论您采用哪种方法,您都可能想要SELECT DISTINCT name...

标签: sql database derby


【解决方案1】:

问题是您的子查询返回多个结果,因此您必须使用 where in=

where ssn = 更改为where ssn in,将where companyid = 更改为where companyid in

【讨论】:

    【解决方案2】:

    尝试使用 IN 关键字而不是 '='。

    尝试将您的查询更改为此

    选择名称 来自公司 公司 ID 在哪里(选择公司 ID
    从就业 在哪里 ssn (选择 ssn 从人 WHERE countryofbirth = 'Mexico');

    【讨论】:

      【解决方案3】:

      用途:

      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'
      

      【讨论】:

      • 实际上,子查询和联接在 SQL Server 上使用相同的查询计划。试试看。
      • 它的性能可能不会更好,但恕我直言,它是一个更容易阅读的 hellofalot
      • @David B:我明天会测试,但问题似乎与 Derby 相关 - 没有 SQL Server。
      【解决方案4】:

      您应该在where 条件中使用In,因为(SELECT ssn FROM Person WHERE countryofbirth = 'Mexico'); 可能会返回多个ssn 值。

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

      【讨论】:

        【解决方案5】:

        尝试使用IN 而不是=

        当你写作时:

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

        子查询必须返回单个值。如果它返回多个值,则会出现错误。

        为了解决这个问题,我们使用了 IN 运算符,它允许子查询返回一组值 (>=0),如果 a 等于其中任何一个值,则您的 where 条件成功。

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

        【讨论】:

          【解决方案6】:

          看看这是否有效

          选择 c.Name FROM PERSON p
          LEFT JOIN 就业 e ON p.ssn=e.ssn LEFT JOIN 公司 c ON e.CompanyID=c.CompanyID WHERE p.countryofbirth=

          【讨论】:

            【解决方案7】:

            错误是由于两个子查询之一返回多行。例如,我认为您可能有多个出生在墨西哥的人。

            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
                        )
            

            【讨论】:

              【解决方案8】:

              最好使用OMG Ponies 的答案JOINs。
              但是,如果您出于某种原因不喜欢JOINs,那么TOP 1 应该为您解决问题:

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

              【讨论】:

                猜你喜欢
                • 2021-01-20
                • 2015-05-29
                • 2011-09-29
                • 2011-10-13
                • 2010-09-07
                • 2010-10-04
                • 2011-01-15
                相关资源
                最近更新 更多