Mysql 通过用户与城市的关系查找国家/地区,其中用户与国家/地区的所有城市相关

Mysql 通过用户与城市的关系查找国家/地区,其中用户与国家/地区的所有城市相关,mysql,sql,doctrine-orm,orm,dql,Mysql,Sql,Doctrine Orm,Orm,Dql,我有四个表:用户、国家、地区和城市 这个国家有许多地区,有许多城市 用户可以与0到多个城市相关(希望访问) 我如何编写一个MySQL查询(或DQL)来找出用户与其完全相关的地区和国家,即希望访问其城市的所有城市?从用户级别开始。然后加入到更大的实体中,并使用distinct减少重复项 SELECT distinct u.user_name ,r.region_name ,co.country_name FROM users u LEFT JOIN cities c ON u.wish

我有四个表:用户、国家、地区和城市

这个国家有许多地区,有许多城市

用户可以与0到多个城市相关(希望访问)


我如何编写一个MySQL查询(或DQL)来找出用户与其完全相关的地区和国家,即希望访问其城市的所有城市?

用户
级别开始。然后加入到更大的实体中,并使用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'
编辑:仅查找用户希望访问的所有国家/地区

发布问题更新后,让我们只拉入用户希望访问其中所有城市的国家。在这种情况下,我们从国家开始,一直到用户。然后我们合计看一个国家的城市被占领的百分比

关键是只加入我们关心的用户(而不是由他们过滤,这将消除
NULL
,用户与城市不匹配)。在所有这些之后,一个简单的
拥有
将帮助我们只筛选具有完整匹配的国家

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'

对国家队你也可以这样做。如果您不明白,请告诉我。

使用
不存在
左连接

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
)

这将包括在愿望列表中甚至只有一个城市的国家。因此,您可以使用where子句
where u.userID=SOMEID
之类的过滤器。您可以在问题中定义表格的模式吗?这将有助于您是否意识到我需要用户希望访问其所有城市而不是其中一个城市的国家?@MedUnes I没有。更新以反映变化。