通过用户与城市关系查找国家/地区,其中用户与一个国家/地区的所有城市相关
Find countries by a user to city relationship where a user is related to all cities of a country
我有四个表:用户、国家、地区和城市
国家有很多地区,有很多城市。
一个用户可以关联到 0 对多的城市(希望访问)。
我如何编写 MySQL 查询(或 DQL)来找出用户与他们 完全 相关的地区和国家,即希望访问 他们所有个城市?
从 User
级开始。然后加入更大的实体,并使用 distinct 来减少重复。
SELECT distinct
u.user_name
,r.region_name
,co.country_name
FROM users u
LEFT JOIN cities c ON u.wish_to_visit = c.city_name
LEFT JOIN regions r ON c.region = r.region_name
LEFT JOIN countries co ON r.country = co.country_name
WHERE u.user_name = 'John Doe'
编辑:仅查找用户想要访问的所有国家/地区
Post 问题更新,让我们只拉入用户想要访问其中所有城市的国家。在这种情况下,我们从国家开始,一直到用户。然后我们汇总以查看一个国家/地区的城市被捕获的百分比。
关键是只加入我们关心的用户(不过不要按他们过滤,这将消除 NULL
,其中用户与城市不匹配)。毕竟,一个简单的 HAVING
将帮助我们过滤出完全匹配的国家。
SELECT
c.country_name
,count(ci.city_name) as count_all_cities
,count(u.wish_to_visit) as count_user_cities
FROM countries c
LEFT JOIN regions r ON c.country_name = r.country
LEFT JOIN cities ci ON r.region_name = ci.region
LEFT JOIN users u ON ci.city_name = u.wish_to_visit AND u.user_name = 'John Doe'
GROUP BY c.country_name
HAVING count(ci.city_name) = count(u.wish_to_visit)
使用连接
select cu.country_name, r.region_name from User u join City c
on u.cityID=c.cityID join Region r on
c.regionID=r.regionID join Country cu
on r.countryID=cu.countryID
where u.userID=SOMEID
对于区域,比较城市数量和最大城市数量会很容易
SELECT user_id,
Region_count.region_id
FROM User
JOIN
(SELECT user_id, region_id, count(*) as reg_user_count
FROM City
WHERE user_id='ThisUser'
GROUP BY region_id) Region_Count
ON Region_Count.user_id=User.user_id
JOIN
(SELECT region_id, count(*) as reg_max
FROM City
GROUP BY region_id) as Region_Max
ON Region_Max.region_id=Region_Count.region_id
AND Region_Max.reg_max=Region_Count.reg_user_count
WHERE user_id='ThisUser'
你可以对国家做同样的事情。如果你想不通,请告诉我。
使用NOT EXISTS
和LEFT JOIN
SELECT *
FROM Region r
WHERE NOT EXISTS(
SELECT 1
FROM City c
LEFT JOIN User u ON c.id_city = u.id_city and u.id_user = 'user_id'
WHERE c.id_reg = r.id_reg and u.id_user IS NULL
)
这将仅查找用户希望访问所有城市的区域,但是,如果您想要访问国家/地区,则只需稍作修改
SELECT *
FROM Country ctr
WHERE NOT EXISTS(
SELECT 1
FROM Region r
LEFT JOIN City c ON r.id_reg = c.id_reg
LEFT JOIN User u ON c.id_city = u.id_city and u.id_user = 'user_id'
WHERE ctr.id_country = r.id_country and u.id_user IS NULL
)
我有四个表:用户、国家、地区和城市
国家有很多地区,有很多城市。
一个用户可以关联到 0 对多的城市(希望访问)。
我如何编写 MySQL 查询(或 DQL)来找出用户与他们 完全 相关的地区和国家,即希望访问 他们所有个城市?
从 User
级开始。然后加入更大的实体,并使用 distinct 来减少重复。
SELECT distinct
u.user_name
,r.region_name
,co.country_name
FROM users u
LEFT JOIN cities c ON u.wish_to_visit = c.city_name
LEFT JOIN regions r ON c.region = r.region_name
LEFT JOIN countries co ON r.country = co.country_name
WHERE u.user_name = 'John Doe'
编辑:仅查找用户想要访问的所有国家/地区
Post 问题更新,让我们只拉入用户想要访问其中所有城市的国家。在这种情况下,我们从国家开始,一直到用户。然后我们汇总以查看一个国家/地区的城市被捕获的百分比。
关键是只加入我们关心的用户(不过不要按他们过滤,这将消除 NULL
,其中用户与城市不匹配)。毕竟,一个简单的 HAVING
将帮助我们过滤出完全匹配的国家。
SELECT
c.country_name
,count(ci.city_name) as count_all_cities
,count(u.wish_to_visit) as count_user_cities
FROM countries c
LEFT JOIN regions r ON c.country_name = r.country
LEFT JOIN cities ci ON r.region_name = ci.region
LEFT JOIN users u ON ci.city_name = u.wish_to_visit AND u.user_name = 'John Doe'
GROUP BY c.country_name
HAVING count(ci.city_name) = count(u.wish_to_visit)
使用连接
select cu.country_name, r.region_name from User u join City c
on u.cityID=c.cityID join Region r on
c.regionID=r.regionID join Country cu
on r.countryID=cu.countryID
where u.userID=SOMEID
对于区域,比较城市数量和最大城市数量会很容易
SELECT user_id,
Region_count.region_id
FROM User
JOIN
(SELECT user_id, region_id, count(*) as reg_user_count
FROM City
WHERE user_id='ThisUser'
GROUP BY region_id) Region_Count
ON Region_Count.user_id=User.user_id
JOIN
(SELECT region_id, count(*) as reg_max
FROM City
GROUP BY region_id) as Region_Max
ON Region_Max.region_id=Region_Count.region_id
AND Region_Max.reg_max=Region_Count.reg_user_count
WHERE user_id='ThisUser'
你可以对国家做同样的事情。如果你想不通,请告诉我。
使用NOT EXISTS
和LEFT JOIN
SELECT *
FROM Region r
WHERE NOT EXISTS(
SELECT 1
FROM City c
LEFT JOIN User u ON c.id_city = u.id_city and u.id_user = 'user_id'
WHERE c.id_reg = r.id_reg and u.id_user IS NULL
)
这将仅查找用户希望访问所有城市的区域,但是,如果您想要访问国家/地区,则只需稍作修改
SELECT *
FROM Country ctr
WHERE NOT EXISTS(
SELECT 1
FROM Region r
LEFT JOIN City c ON r.id_reg = c.id_reg
LEFT JOIN User u ON c.id_city = u.id_city and u.id_user = 'user_id'
WHERE ctr.id_country = r.id_country and u.id_user IS NULL
)