【问题标题】:Find countries by a user to city relationship where a user is related to all cities of a country按用户与城市的关系查找国家/地区,其中用户与一个国家/地区的所有城市相关
【发布时间】:2018-02-14 07:52:20
【问题描述】:

我有四个表:User、Country、Region 和 City

国家有很多地区,也有很多城市。

用户可以与 0 对多的城市相关联(希望访问)。

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

【问题讨论】:

    标签: mysql sql doctrine-orm orm dql


    【解决方案1】:

    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'
    

    编辑:仅查找用户想要访问的国家/地区 ALL

    发布问题更新,让我们只提取用户想要访问其中所有城市的国家/地区。在这种情况下,我们从国家开始,一直到用户。然后我们汇总看看一个国家的城市有多少百分比被捕获。

    关键是只加入我们关心的用户(但不要按他们过滤,这将消除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)
    

    【讨论】:

    • 您是否意识到我需要用户希望访问所有他们的城市而不是一个他们的城市的国家?
    • @MedUnes 我没有。更新以反映变化。
    【解决方案2】:

    使用连接

    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
    

    【讨论】:

    • 这将包括在愿望清单中甚至有一个城市的国家
    • 因此您可以使用过滤器,例如 where 子句 where u.userID=SOMEID
    • 你能在你的问题中定义表的架构吗?
    【解决方案3】:

    对于区域,可以很容易地将城市数量与最大城市数量进行比较

    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'
    

    你可以对国家做同样的事情。如果您无法弄清楚,请告诉我。

    【讨论】:

      【解决方案4】:

      使用NOT EXISTSLEFT 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
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-28
        • 2011-10-12
        • 2012-03-29
        • 2019-10-27
        • 2015-11-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多