SQL 将检索包含另一组所有条目的组的查询

SQL query that will retrieve set containing all entries from another set

我的数据库中有以下关系:

机构:政经机构信息。
名称:机构全称
abbreviation:简称

isMember:政治和经济组织的成员资格。
organization: 组织的简称
country: 成员国代码

geo_desert:沙漠地理信息
desert:沙漠名称
country:所在国家代码located
province: 这个国家的省份

我的任务是检索其成员中包含沙漠国家的完整集合的组织。这个组织也可以有没有沙漠的国家。所以我有一组有沙漠的国家,结果每个组织都应该有所有这些国家和任意数量的其他(没有沙漠)国家。

到目前为止,我尝试编写了以下代码,但它不起作用。

WITH CountriesWithDeserts AS (
    SELECT DISTINCT country
    FROM dbmaster.geo_desert        
), OrganizationsWithAllDesertMembers AS (
    SELECT organization 
    FROM dbmaster.isMember AS ism 
    WHERE (
        SELECT count(*)
        FROM (
            SELECT *
            FROM  CountriesWithDeserts          
            EXCEPT
            SELECT country
            FROM dbmaster.isMember
            WHERE organization = ism.organization
        )
    ) IS NULL
), OrganizationCode AS (
    SELECT name, abbreviation
    FROM dbmaster.Organization  
)
SELECT oc.name AS Organization
FROM OrganizationCode AS oc, OrganizationsWithAllDesertMembers AS owadm
WHERE oc.abbreviation=owadm.organization;

更新: 数据库管理系统说:"ism.organization is not defined"
我正在使用 DB2/LINUXX8664 9.7.0

输出应如下所示:

名称
-------------------------------------- --------------------------------------
非洲、加勒比和太平洋国家
非洲开发银行
文化和技术合作署
安第斯集团

我发现处理此问题的最简单方法是使用 group byhaving。你只想专注于沙漠,所以其他国家并不重要。

select m.organization
from isMember m join
     geo_desert d
     on m.country = d.country
group by m.organization
having count(distinct m.country) = (select count(distinct d.country) from geo_desert);

having 子句简单地计算匹配(即沙漠)国家的数量并检查是否包含所有国家。

这样说:您正在寻找不存在沙漠国家的组织。

select *
from organization o
where not exists
(
  select country from geo_desert
  except
  select country from ismember
  where organization = o.abbreviation
);

这里有两个等效的解决方案:


第一个:

WITH CountriesWithDeserts AS (
    SELECT DISTINCT country
    FROM dbmaster.geo_desert        
), OrganizationsWithAllDesertMembers AS (
    SELECT ism.organization 
    FROM dbmaster.isMember AS ism
    JOIN CountriesWithDeserts AS cwd
    ON ism.country = cwd.country
    GROUP BY ism.organization
    HAVING count(ism.country) = (SELECT count(*) FROM CountriesWithDeserts)
), OrganizationCode AS (
    SELECT name, abbreviation
    FROM dbmaster.Organization  
)
SELECT oc.name AS Organization
FROM OrganizationCode AS oc, OrganizationsWithAllDesertMembers AS owadm
WHERE oc.abbreviation=owadm.organization;

第二个:

WITH CountriesWithDeserts AS (
    SELECT DISTINCT country
    FROM dbmaster.geo_desert        
)
SELECT org.name AS Organization
FROM dbmaster.Organization AS org
WHERE NOT EXISTS (
    SELECT *
    FROM  CountriesWithDeserts          
    EXCEPT
    SELECT country
    FROM dbmaster.isMember
    WHERE organization = org.abbreviation
);