与MySQL的多个连接,获得意想不到的结果

时间:2015-04-03 02:55:12

标签: mysql

我正在尝试加入3个表,但看起来我做错了。另外我不确定INNER JOIN在这里是不是一个好主意,因为在其他表中可能会有一些缺少对应的行,但我仍然希望它们显示为NULL,然后LEFT JOIN可能会更好,但同样,我和做错了。

表格回复的快速摘要:

SELECT geonameid, name, iso_alpha2, admin1_code
FROM maxmind_cities1000
WHERE name LIKE 'tron%' LIMIT 20;

+-----------+------------------------+------------+-------------+
| geonameid | name                   | iso_alpha2 | admin1_code |
+-----------+------------------------+------------+-------------+
|   1605268 | Tron                   | TH         | 10          |
|   8949073 | Tronca                 | IT         | 03          |
|   3107444 | Tronchón               | ES         | 52          |
|   8859151 | Tronconal              | MX         | 21          |
|   2821000 | Tröndel                | DE         | 10          |
|   3133880 | Trondheim              | NO         | 16          |
|   1252408 | Trongsa                | BT         | 21          |
|   2667264 | Trönninge              | SE         | 06          |
|   6535739 | Trontano               | IT         | 12          |
|   2971582 | Tronville-en-Barrois   | FR         | B2          |
|   3165134 | Tronzano Lago Maggiore | IT         | 09          |
|   3165133 | Tronzano Vercellese    | IT         | 12          |
+-----------+------------------------+------------+-------------+

SELECT iso_alpha2, name
FROM maxmind_countryinfo
WHERE iso_alpha2 = 'NO';

+------------+--------+
| iso_alpha2 | name   |
+------------+--------+
| NO         | Norway |
+------------+--------+

SELECT code, name_local
FROM maxmind_admin1_codes_ascii
WHERE code = 'NO.16';

+-------+-----------------+
| code  | name_local      |
+-------+-----------------+
| NO.16 | Sør-Trøndelag   |
+-------+-----------------+

所以基本上我试图用这个查询加入这三个表,我做了一个特例并说ON admin1.code = 'NO.16'

SELECT
    city.geonameid as city_id,
    city.name as city_name,
    country.name as country_name,
    admin1.name_local as admin1_code
FROM maxmind_cities1000 as city
    INNER JOIN maxmind_countryinfo as country
        ON city.iso_alpha2 = country.iso_alpha2
    INNER JOIN maxmind_admin1_codes_ascii as admin1
        ON admin1.code = 'NO.16'
WHERE city.name LIKE 'tron%' LIMIT 20;

但它反正给了我所有的行而不仅仅是特隆赫姆挪威,所以我在这里做错了。我尝试切换到LEFT JOIN但得到相同的结果集。即使maxmind_admin1_codes_ascii表中没有匹配的行,我希望城市显示在结果集中,管理代码的格式为iso_aplha2'。' admin1_code

+---------+------------------------+--------------+-----------------+
| city_id | city_name              | country_name | admin1_code     |
+---------+------------------------+--------------+-----------------+
| 1605268 | Tron                   | Thailand     | Sør-Trøndelag   |
| 8949073 | Tronca                 | Italy        | Sør-Trøndelag   |
| 3107444 | Tronchón               | Spain        | Sør-Trøndelag   |
| 8859151 | Tronconal              | Mexico       | Sør-Trøndelag   |
| 2821000 | Tröndel                | Germany      | Sør-Trøndelag   |
| 3133880 | Trondheim              | Norway       | Sør-Trøndelag   |
| 1252408 | Trongsa                | Bhutan       | Sør-Trøndelag   |
| 2667264 | Trönninge              | Sweden       | Sør-Trøndelag   |
| 6535739 | Trontano               | Italy        | Sør-Trøndelag   |
| 2971582 | Tronville-en-Barrois   | France       | Sør-Trøndelag   |
| 3165134 | Tronzano Lago Maggiore | Italy        | Sør-Trøndelag   |
| 3165133 | Tronzano Vercellese    | Italy        | Sør-Trøndelag   |
+---------+------------------------+--------------+-----------------+

这是我的最终结果查询,但仍然不明白为什么当我只想要特殊情况' NO.16'时它为我提供了所有结果。如果我想要显示城市而不管maxmind_admin1_codes_ascii表中没有匹配的行,我应该如何构建我的查询?这就是我到目前为止所拥有的

SELECT
    city.geonameid as city_id,
    city.name as city_name,
    country.name as country_name,
    admin1.name_local as admin1_code
FROM maxmind_cities1000 as city
    INNER JOIN maxmind_countryinfo as country
        ON city.iso_alpha2 = country.iso_alpha2
    INNER JOIN maxmind_admin1_codes_ascii as admin1
        ON admin1.code = CONCAT(city.iso_alpha2, '.', city.admin1_code)
WHERE city.name LIKE 'tron%' LIMIT 20;

+---------+------------------------+--------------+--------------------+
| city_id | city_name              | country_name | admin1_code        |
+---------+------------------------+--------------+--------------------+
| 1605268 | Tron                   | Thailand     | Uttaradit          |
| 8949073 | Tronca                 | Italy        | Calabria           |
| 3107444 | Tronchón               | Spain        | Aragon             |
| 8859151 | Tronconal              | Mexico       | Puebla             |
| 2821000 | Tröndel                | Germany      | Schleswig-Holstein |
| 3133880 | Trondheim              | Norway       | Sør-Trøndelag      |
| 1252408 | Trongsa                | Bhutan       | Tongsa             |
| 2667264 | Trönninge              | Sweden       | Halland            |
| 6535739 | Trontano               | Italy        | Piedmont           |
| 2971582 | Tronville-en-Barrois   | France       | Lorraine           |
| 3165134 | Tronzano Lago Maggiore | Italy        | Lombardy           |
| 3165133 | Tronzano Vercellese    | Italy        | Piedmont           |
+---------+------------------------+--------------+--------------------+

这给出了我想要的结果,但我不认为我做得对,因为结果出乎意料的是#16; NO.16'的特殊情况。希望有人可以帮忙!

2 个答案:

答案 0 :(得分:0)

SELECT
    city.geonameid as city_id,
    city.name as city_name,
    country.name as country_name,
    admin1.name_local as admin1_code
FROM maxmind_cities1000 as city
    INNER JOIN maxmind_countryinfo as country
        ON city.iso_alpha2 = country.iso_alpha2
    INNER JOIN maxmind_admin1_codes_ascii as admin1
        ON admin1.code = city.admin1_code
WHERE city.name LIKE 'tron%' LIMIT 20 AND city.admin1_code = 'NO.16';

答案 1 :(得分:0)

不完全确定我是否理解你想要做什么 - 但也许这个?

SELECT
    city.geonameid as city_id,
    city.name as city_name,
    country.name as country_name,
    admin1.name_local as admin1_code
FROM maxmind_cities1000 as city
    INNER JOIN maxmind_countryinfo as country
        ON city.iso_alpha2 = country.iso_alpha2
    LEFT OUTER JOIN maxmind_admin1_codes_ascii as admin1
        ON admin1.code = CONCAT(city.iso_alpha2, '.', city.admin1_code)
        AND admin1.code = 'NO.16'
WHERE city.name LIKE 'tron%' LIMIT 20;