所以我有这个问题,我必须在ismember表中显示不属于组织"世界卫生组织"的名称或国家。这是我提出的的SQL
SELECT DISTINCT ismember.country, country.name
FROM ismember LEFT JOIN country ON ismember.country = country.code
WHERE ismember.organization NOT IN (
SELECT DISTINCT ismember.organization
FROM ismember
WHERE ismember.organization = 'WHO'
)
GROUP BY organization
HAVING COUNT(organization) > 1 ;
它起作用,而且它确实让那些不在"世界卫生组织"的国家返回。我的问题是,这种方法排除了不属于任何组织的国家。I.E它不包括那些在成员表中没有条目的国家。
任何想法如何解决
为什么不做这样的事情?
SELECT code, name FROM country WHERE code NOT IN (
SELECT country FROM ismember WHERE organization = 'WHO'
)
应该做同样的事情。:)
实现这一点的一种方法是简单地使用聚合和having
子句:
SELECT im.country, c.name
FROM ismember im LEFT JOIN
country c
ON im.country = c.code
GROUP BY m.country, c.name
HAVING SUM(im.organization = 'WHO') = 0;
这不是答案,而是对查询作用的解释:
-
子查询
选择成员或组织的差异FROM ismember其中ismember.organization="世界卫生组织"
这为表中组织为"世界卫生组织"的每个记录获取字符串"世界卫生组织",然后将所有"世界卫生组织"减少为一个"世界卫生组织"。
- 不在
因此WHERE ismember.organization NOT IN (subquery)
与WHERE ismember.organization <> 'WHO'
相同
- 左联接
你左外加入桌国成为会员。这意味着,如果一个成员包含一个不在国家表中的国家,你仍然可以获得该记录。但是,为什么一个国家不在国家名单上呢?这似乎没有道理。你可能会得到一个像123, NULL
这样的记录,这意味着国家代码123不是有效的国家,但到底是什么呢?
- 分组依据
您按组织分组。因此,每个组织会得到一个结果行。你不是说要把国家列入名单吗?
- 聚合
然后选择ismember.country和country.name per organization。由于您没有指定任何所需的聚合,如MAX(ismember.country)或MIN(country.name),因此会得到一个随机匹配。所以,如果有一个国家为1、2和3的组织"ABC",你可以随机得到这三个组织中的一个。
- 具有
HAVING COUNT(organization)
与HAVING COUNT(*)
大致相同,即每个组织的国家数。确切地说:所有非null的组织都是一样的(对于null,第一个表达式为0,第二个表达式为country count)。您希望该组织的国家/地区计数大于1。因此,您删除了只有一个成员的组织。
- 明显的
如果"ABC"的随机国家代码是1,随机国家名称是"Italy"(它们不必属于一起,两者只是组织的独立随机选择),而同一对恰好是组织"DEF"的选择,那么你应该删除其中一个,这样你就只得到1,"Italy'一次。
- 惊喜
我很惊讶你说这个查询有一个小缺陷。对不起,我觉得很难相信。