【问题标题】:MySQL error 1242: Subquery returns more than 1 rowMySQL 错误 1242:子查询返回多于 1 行
【发布时间】:2015-05-04 21:51:53
【问题描述】:

我正在做一些 SQL 作业,但我在这个问题上遇到了死胡同,我希望有人能指出我在这里到底做错了什么。

SELECT Name,
    (SELECT Name
    FROM City
    WHERE City.CountryCode = Country.Code) AS 'city',

    (SELECT Population
    FROM City
    WHERE City.CountryCode = Country.Code) AS 'city_population'
FROM Country
WHERE Region IN ('Western Europe')
HAVING city_population > (SUM(Population) / COUNT(city))
ORDER BY Name, city;

我在这里尝试做的是从全球统计数据库中检索与该表中的国家/地区匹配的城市列表(来自城市表),其中国家位于西欧地区和城市人口大于其国家城市的平均人口,按国家和城市名称排序。 CountryCode 和 Code 是表的键。

谁能告诉我哪里出错了?我猜 MySQL 很不高兴,因为我的子查询返回的行数比国家名称选择器返回的行数多,但这正是我想要做的。我想要一个国家值的多行,每个满足大于平均人口的搜索条件的城市一行。该作业还明确禁止我使用连接来解决此问题。

【问题讨论】:

  • 您应该为此使用连接。
  • 你需要一个子选择来按国家/地区获得平均人口
  • 不幸的是,我被明确禁止使用连接来解决这个问题。
  • 可能在 WHERE 中使用多个子查询(相关的和不相关的)?

标签: mysql sql database


【解决方案1】:

连接应该做到这一点。您可以根据国家代码加入城市,并过滤掉人口低于平均水平的城市

select
  co.Name as CountryName,
  ci.Name as CityName,
  ci.Population as CityPopulation
from
  Country co
inner join City ci 
  on ci.CountryCode = co.CountryCode 
where
  co.Region in ('Western Europe')
  and ci.Population > 
    (select sum(ca.Population) / count(*) from City ca 
     where ca.CountryCode = co.CountryCode)

补充: 由于不允许使用联接,因此可以通过多种方式解决。

1) 您可以稍微更改您的查询,但它不会返回每个城市的行。相反,它将城市列表作为单个字段返回。这只是对您的查询的轻微修改。请注意GROUP_CONCAT 函数,它的工作方式类似于SUM,只是它连接值而不是求和它们。还要注意子选择中添加的ORDER BY 子句,因此您可以确保第 n 个人口与第 n 个城市名称匹配。

SELECT Name,
    (SELECT GROUP_CONCAT(Name)
    FROM City
    WHERE City.CountryCode = Country.Code
    ORDER BY City.Name) AS 'city',

    (SELECT GROUP_CONCAT(Population)
    FROM City
    WHERE City.CountryCode = Country.Code
    ORDER BY City.Name) AS 'city_population'
FROM Country
WHERE Region IN ('Western Europe')
HAVING city_population > (SUM(Population) / COUNT(city))
ORDER BY Name, city;

2) 您可以通过查询稍作更改。删除 Country 上的连接,而是在过滤器和选择中使用一些子选择。仅当您需要国家名称时才需要后者。如果国家代码足够,您可以从城市中选择。

select
  (select County.Name 
   from Country 
   where County.CountyCode = ci.CountryCode) as CountryName,
  ci.CountryCode,
  ci.Name as CityName,
  ci.Population
from
  City ci 
where
  -- Select only cities in these countries.
  ci.CountryCode in
    ( select co.CountryCode 
      from Country co
      where co.Region in ('Western Europe'))
  -- Select only cities of above avarage population.
  -- This is the same subselect that existed in the join before, 
  -- except it matches on CountryCode of the other 'instance' of 
  -- of the City table. Note, you will _need_ to use aliases (ca/ci)
  -- here to make it work.
  and ci.Population > 
    ( select sum(ca.Population) / count(*) 
      from City ca 
      where ca.CountryCode = ci.CountryCode)

【讨论】:

  • 谢谢,这有帮助,不幸的是,我被明确告知不要使用连接,所以我重写了它以在 FROM 子句中使用子查询。 SELECT Name, (SELECT Name FROM City ci WHERE ci.CountryCode = Country.Code) AS 'city', city_population FROM (SELECT Population AS 'city_population' FROM City ci WHERE ci.CountryCode = Country.Code AND ci.Population > SUM( ci.Population) / COUNT(*)) WHERE Region IN ('Western Europe') ORDER BY Name, ci.Name;我收到一个错误,即每个派生表都必须有自己的别名。不知道我在哪里错过它
  • 您收到该错误是因为您的子查询没有别名。(selec...) AS subQname
  • 好的,现在我有了:SELECT Name, (SELECT Name FROM City WHERE City.CountryCode = Country.Code) AS 'city', city_population FROM (SELECT Population FROM City WHERE City.CountryCode = Country.Code AND City.Population > SUM(City.Population) / COUNT(*)) AS city_population WHERE Region IN ('Western Europe') ORDER BY Name, City.Name;我收到一个错误:Unknown Column: Country.Code in where 子句。不知道为什么突然不想工作。
  • Country 在主查询中不可用,因此您不能在那里使用 Country.Code。我添加了两种可能的解决方案,最后一个与您尝试做的匹配,但我认为它应该可以工作(没有数据库来测试它,所以这只是一些微弱的 Notepad++ 尝试)。
【解决方案2】:

语句的选择部分中的子查询只期望从查询返回一个值。请记住,在您的选择语句中分隔值的逗号代表列,并且每一列都需要一个值。为了获得子查询中返回的值列表(就好像它是另一个表一样)并在外部查询中使用它,您必须将子查询放在查询的from 部分中。注意:这可能不是您结果的正确代码。我只是在解决 MySQL 错误 1242 的问题。

SELECT Name   
FROM Country, (SELECT Name
    FROM City
    WHERE City.CountryCode = Country.Code) AS 'city',

    (SELECT Population
    FROM City
    WHERE City.CountryCode = Country.Code) AS 'city_population'
WHERE Region IN ('Western Europe')
HAVING city_population > (SUM(Population) / COUNT(city))
ORDER BY Name, city;

【讨论】:

    猜你喜欢
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多