City_Name (PK) State_Name (PK) Population
-------------- --------------- ----------
Austin MA
Austin TX
Burlington VT
Fresno CA
Houston TX
Independence KS
Independence MO
Independence PA
Kansas CA
Kansas MO
Paris MO
Paris OR
Paris TX
Paris VA
Paso TX
上表有一个复合主键(City_Name和State_Name)。我想找到恰好发生在两个不同国家的城市(不多也不少)。在这种情况下,结果将是
City_Name
---------
Austin
Kansas
其他城市不符合条件,因为它们出现在一个或两个以上的州。这个解决方案是练习关系演算问题所必需的,因此(不幸的是)不能使用任何聚合函数,如COUNT()。
期待收到一些善良的人的回复。
注意 - 没有找到任何线索从哪里开始,因此不会显示任何努力:(
答案 0 :(得分:4)
select distinct c1.city_name
from city c1
join city c2
on c2.city_name = c1.city_name
and c1.state_name <> c2.state_name
where not exists (select 1
from city c3
where c3.city_name = c1.city_name
and c3.state_name not in (c1.state_name, c2.state_name));
SQLFiddle:http://sqlfiddle.com/#!2/7d0901/8
答案 1 :(得分:2)
似乎mysql不支持minus / except:
-- two or more states
select c1.city_name
from city c1
join city c2
on c1.city_name = c2.city_name
and c1.state_name<>c2.state_name
minus
-- three or more states
select c1.city_name
from city c1 join city c2
on c1.city_name = c2.city_name
and c1.state_name<>c2.state_name
join city c3
on c1.city_name = c3.city_name
and c1.state_name <> c3.state_name
and c2.state_name <> c3.state_name;
使用not in:
进行重写-- two or more states
select distinct c1.city_name
from city c1
join city c2
on c1.city_name = c2.city_name
and c1.state_name<>c2.state_name
where c1.city_name not in (
-- three or more states
select c1.city_name
from city c1
join city c2
on c1.city_name = c2.city_name
and c1.state_name<>c2.state_name
join city c3
on c1.city_name = c3.city_name
and c1.state_name <> c3.state_name
and c2.state_name <> c3.state_name
);
答案 2 :(得分:2)
@ a_horse_with_no_name的答案是一个非常好(并且直截了当)的解决方案。以下是完成同样事情的另一种方式:
SELECT DISTINCT c1.city_name
FROM city c1
JOIN city c2
ON c2.city_name = c1.city_name AND c1.state_name <> c2.state_name
LEFT JOIN city c3
ON c1.city_name = c3.city_name
AND c3.state_name NOT IN (c1.state_name, c2.state_name)
WHERE c3.city_name IS NULL
此解决方案在FROM
子句中创建一组2-3个城市,然后使用where
子句清除那些拥有第三个城市的城市。
答案 3 :(得分:1)
因此,此查询将计算重复行的数量,并将删除计数高于2的那些以及计数较低的那些2.尝试出来! :)
SELECT DISTINCT city_name
FROM city
WHERE city_name NOT IN
( SELECT IF(counting_col > 2, city_name, NULL) AS city_name_s
FROM
( SELECT city_name, IF(@A = city_name, @B := @B + 1, @B := 1) AS counting_col, @A := city_name
FROM city
CROSS JOIN (SELECT @A := '', @B := 1) t
ORDER BY city_name
) t1
HAVING city_name_s IS NOT NULL
)
AND city_name IN
( SELECT IF(counting_col = 2, city_name, NULL) AS city_name_s
FROM
( SELECT city_name, IF(@A = city_name, @B := @B + 1, @B := 1) AS counting_col, @A := city_name
FROM city
CROSS JOIN (SELECT @A := '', @B := 1) t
ORDER BY city_name
) t1
HAVING city_name_s IS NOT NULL
)