MySQL将连接限制保留为一行

时间:2014-02-21 16:15:09

标签: mysql sql

我有以下数据库结构

table_countries
----------
country_id
country_name

table_cities
----------
city_id
country_id
city_name

table_streets
----------
street_id
city_id
street_name

table_people
----------
person_id
street_id
person_name

有多个国家,可以有多个城市,而这些城市又有多条街道等等。

我希望执行一个查询,该查询将获得包含1个或更多人的所有国家/地区的列表。

问题是国家表没有直接链接到人员表。 LEFT JOIN为同一个国家/地区返回多行。

4 个答案:

答案 0 :(得分:5)

对于编辑中提到的预期结果,我将左连接更改为内连接,并仅选择具有group by子句的国家/地区名称。注意on子句中的外键名称,我认为你必须澄清/纠正你的表结构:

SELECT 
    table1.country

FROM
   table1 JOIN table2 ON table1.id = table2.table1_id
   JOIN table3 ON table2.id = table3.table2_id
   JOIN table4 ON table3.id = table4.table3_id

GROUP BY
    table1.country

答案 1 :(得分:2)

SELECT * FROM table1 WHERE id IN (
SELECT DISTINCT table1.id
  FROM table1
  LEFT JOIN table2
         ON table1.id = table2.id
  LEFT JOIN table3
         ON table2.id = table3.id
  LEFT JOIN table4
         ON table3.id = table4.id
);

应该做的伎俩呢?您甚至不需要DISTINCT,但如果您只想获取国家/地区ID,则会使内部查询足够。

答案 2 :(得分:2)

你的问题超出了返回重复国家的范围。基本上,对于列表中的任何资源,都存在重复的可能性。例如,如果您有两条道路为“洛杉矶”城市,那么“洛杉矶”将在同一个国家/地区出现两次。

要解决此问题,您可以:1)对要返回的每个资源(错误的想法)单独查询,或者2)只处理代码中输出类别的重复行。

像这样:

$categories = array();
foreach ($results as $row) {
    if (!isset($categories[$row->country])) {
        $categories[$row->country] = array(
            'name' => $row->countryName,
            'cities' => array(),
        );        
    }
    if (!isset($categories[$row->country]['cities'][$row->city])) {
        $categories[$row->country]['cities'][$row->city] = array(
            'name' => $row->cityName,
            'roads' => array();
        );  
    }

    // ... and so on, with roads and people
}

上面将按照国家/地区分为一组按道路,道路分组和城市分组的人员;您可以使用它以您希望的任何方式输出数据。当然,您也可以修改上面的代码,立即输出数据,而不是先将它存储在数组中。

另外,如果您只想返回有人的国家,我会这样做:

SELECT *
FROM table1
   LEFT JOIN table2
             ON table1.id = table2.id
   LEFT JOIN table3
             ON table2.id = table3.id
   LEFT JOIN table4
             ON table3.id = table4.id
   WHERE table4.id IS NOT NULL

答案 3 :(得分:0)

2)

SELECT * 
  FROM table1 
 WHERE id IN (
              SELECT id 
                FROM table4)

1)不可能

相关问题