2012-09-17 71 views
1

我查询的目标是返回国家,大写和所用语言的数量。它还需要按照语言数量的降序排列,然后由大写字母排序。最后,语言的数量必须至少为5和10或更少。SQL查询无法正常工作,返回任何内容

这里是我的查询:

SELECT country.name     AS Country, 
     city.name      AS Capital, 
     Count(countrylanguage.language) AS NumLanguages 
FROM country, 
     city, 
     countrylanguage 
WHERE city.id = country.capital 
GROUP BY city.name, 
      country.name 
HAVING (Count(countrylanguage.language) BETWEEN 5 AND 10); 

它没有返回。 where子句是必需的,才能显示城市名称。在国家表中只是一个身份证号码,然后城市名单中包含身份证号码和姓名。

如果任何人都可以发现我的错误我“将非常感谢!

+0

这是功课?这很好,如果是这样,最好提一下。 –

回答

4

你缺少与countrylanguage的关系。没有它,你有一个笛卡尔积,因此Count(countrylanguage.language)等于记录在countrylanguage的数量,这是最有可能是大于10

这里有一个建议的解决方案(调整字段名/ DB结构相应地):

SELECT country.name     AS Country, 
     city.name      AS Capital, 
     Count(countrylanguage.language) AS NumLanguages 
FROM country, 
     city, 
     countrylanguage 
WHERE city.id = country.capital 
AND countrylanguage.language_id = country.language_id 
GROUP BY city.name, 
      country.name 
HAVING (Count(countrylanguage.language) BETWEEN 5 AND 10) 
ORDER BY NumLanguages desc, city.Name 

这就是说,你应该在尽量避免在查询的WHERE子句中加入连接(隐式连接)。使用显式(声明式)连接会给你更多的可读性和更多的灵活性。

更新

按照意见建议,这里是一个使用ANSI-92连接语法查询的版本:

SELECT country.name     AS Country, 
     city.name      AS Capital, 
     Count(countrylanguage.language) AS NumLanguages 
FROM  country 
INNER JOIN city on city.id = country.capital 
INNER JOIN countrylanguage on countrylanguage.language_id = country.language_id 
GROUP BY city.name, 
      country.name 
HAVING (Count(countrylanguage.language) BETWEEN 5 AND 10); 
ORDER BY NumLanguages desc, city.Name 
+1

如果有效,我印象深刻。正如OP所说,笛卡尔产品会返回太多的行,而不是任何行。 – ahillman3

+1

@ ahillman3阅读我更新的答案。 OP希望团体'HAVING(Count(countrylanguage.language)between 5 and 10)',所以**许多**最有可能超过10 –

+1

@ ahillman3 - 我同意这可能是解释。没有ANSI-92连接语法?如果OP首先使用它,他们不会有这个问题... –