【问题标题】:How to write an "exclusive" query in SQL?如何在 SQL 中编写“排他”查询?
【发布时间】:2012-04-10 20:56:51
【问题描述】:

我正在查看我正在学习的数据库课程的过去论文,但我遇到了一个 SQL 问题

这是提供的架构

  • 国家(名称、首都、地区),名称是关键

  • People(国家、人口、儿童、成人),其中国家指的是 国家名称,人口是总人口,儿童和成人 是儿童和成人人口的百分比。

  • Language(country,language,percentage) – 对于在 国家,它列出了说该语言的人口百分比。

问题来了:

在 SQL 中编写以下查询:查找在总人口超过 10^7 的国家/地区使用的语言。

这是我目前所拥有的:

SELECT l.language
FROM people p, language l
WHERE l.country = p.country AND
    p.population > 10^7

我有点困惑的是如何检查没有其他国家使用某种语言但人口少于 10^7。

有什么建议吗? 谢谢

【问题讨论】:

  • 因为这是一个数据库课程,你应该阅读正确的连接语法。您使用的是较旧/过时(但仍然有效)的符号,我称之为“惰性语法”。
  • “仅大于 X”表示“不小于或等于 X”
  • 一个花哨的事情(我认为这个问题正在得到解决)是,对于任何给定的语言,问问自己:有多少个国家说它,这些国家中有多少人有 > X 人口?或者您可以问自己:“如果我有两张表,一张的国家人口 > X,另一张

标签: sql database join


【解决方案1】:

获取所有语言。从该集合中删除人口 10^7 的国家/地区使用的语言。

select language from languages
where language not in (
    select language from languages l
    join people p on l.country = p.country
    where p.population <= 10^7)

这是基于您的设计具有必须在至少一个国家/地区使用每种语言的限制;)

【讨论】:

  • 这是一种方式,但(在我有限的经验中)这种方式作为经典/学术解决方案教授,因为它使用子选择。
  • “这是基于……”——我不认为这是一个安全的假设!
  • 如果您想要一个没有子查询的解决方案,请使用 MINUS 组合两个 SELECT。
【解决方案2】:
WITH T 
     AS
     (
      SELECT l.language, 
             p.country, p.population
        FROM people p, language l
       WHERE l.country = p.country
     )
SELECT language
  FROM T
EXCEPT
SELECT language
  FROM T
 WHERE population <= 10000000;

或者:

SELECT language
  FROM language AS l1
 WHERE 10000000 < ( SELECT MIN(p.population)
                      FROM people p, language l
                     WHERE l.country = p.country
                           AND l.language = l1.language );

同样:

SELECT language
  FROM language AS l1
 WHERE 10000000 < ALL ( SELECT p.population
                          FROM people p, language l
                         WHERE l.country = p.country
                               AND l.language = l1.language );

【讨论】:

    【解决方案3】:

    我的方法是让每个规模的国家/地区使用不同的语言,然后左加入这两个列表,最后得到仅在人口大于 10^7(或 10000000)的国家/地区使用的语言列表.

    ;WITH Bigs AS
    (
        SELECT DISTINCT l.language
        FROM people p
        INNER JOIN language l ON l.country = p.country
        WHERE p.population > 10000000
    )
    ,Littles AS
    (
        SELECT DISTINCT l.language
        FROM people p
        INNER JOIN language l ON l.country = p.country
        WHERE p.population <= 10000000
    )
    SELECT b.language 
    FROM Bigs b
    LEFT JOIN Littles l ON l.language = b.language
    WHERE l.language IS NULL
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-04
      • 1970-01-01
      • 2017-12-12
      • 2013-01-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多