我有以下MySQL表:
tbl_pet_owners:
+----+--------+----------+--------+--------------+
| id | name | pet | city | date_adopted |
+----+--------+----------+--------+--------------+
| 1 | jane | cat | Boston | 2017-07-11 |
| 2 | jane | dog | Boston | 2017-07-11 |
| 3 | jane | cat | Boston | 2017-06-11 |
| 4 | jack | cat | Boston | 2016-07-11 |
| 5 | jim | snake | Boston | 2017-07-11 |
| 6 | jim | goldfish | Boston | 2017-07-11 |
| 7 | joseph | cat | NYC | 2016-07-11 |
| 8 | sam | cat | NYC | 2017-07-11 |
| 9 | drew | dog | NYC | 2016-07-11 |
| 10 | jack | frog | Boston | 2017-07-19 |
+----+--------+----------+--------+--------------+
tbl_pet_types:
+----------+-------------+
| pet | type |
+----------+-------------+
| cat | mammal |
| dog | mammal |
| goldfish | fish |
| goldfish | seacreature |
| snake | reptile |
+----------+-------------+
我有以下SQL查询,它会搜索宠物类型列表,以及拥有这些宠物类型的所有者的名称和城市:
SELECT DISTINCT types.type, owners.name, owners.city
FROM tbl_pet_owners owners
LEFT JOIN tbl_pet_types types ON owners.pet = types.pet
WHERE types.type IN ('mammal', 'fish', 'amphibian', 'seacreature');
查询返回:
+-------------+--------+--------+
| type | name | city |
+-------------+--------+--------+
| mammal | jane | Boston |
| mammal | jack | Boston |
| fish | jim | Boston |
| seacreature | jim | Boston |
| mammal | joseph | NYC |
| mammal | sam | NYC |
| mammal | drew | NYC |
+-------------+--------+--------+
结果中省略了两栖动物,因为在tbl_pet_types中找不到它。如何更改我的查询以便行:
amphibian, NULL, NULL
包含在结果中?
答案 0 :(得分:1)
left join
是正确的,但您需要types
成为第一个:
SELECT DISTINCT types.type, owners.name, owners.city
FROM tbl_pet_types types LEFT JOIN
tbl_pet_owners owners
ON owners.pet = types.pet
WHERE types.type IN ('mammal', 'fish', 'amphibian', 'seacreature');
由于WHERE
子句仅指tbl_pet_types
,因此不会更改。
left join
的工作原理很简单:它会将所有行保留在第一个表中。第二个中不匹配的列变为NULL
。
编辑:
如果您有一个不在tbl_pet_types
中的类型列表,那么您需要left join
包含派生表中的所有值:
SELECT DISTINCT tt.type, po.name, po.city
FROM (SELECT 'mammal' as type UNION ALL
SELECT 'fish' as type UNION ALL
SELECT 'amphibian' as type UNION ALL
SELECT 'seacreature' as type
) tt left join
tbl_pet_types pt
ON pt.type = tt.type LEFT JOIN
tbl_pet_owners po
ON po.pet = pt.pet;
答案 1 :(得分:0)
然后执行RIGHT JOIN
而不是LEFT JOIN
说
RIGHT JOIN tbl_pet_types types ON owners.pet = types.pet
如果你想要两个表的外连接结果(不确定关闭),你可以考虑通过混合左右连接来做FULL JOIN
答案 2 :(得分:0)
MySQL STILL 没有CTE吗?它们让生活变得更加轻松。
无论如何,要获得“未找到”,请在SELECT
中使用SELECT DISTINCT p.petType
, coalesce(po.name,'NOT FOUND') AS name
, coalesce(po.city,'NOT FOUND') AS city
FROM (
SELECT 'mammal' AS petType UNION ALL
SELECT 'fish' UNION ALL
SELECT 'amphibian' UNION ALL
SELECT 'seacreature'
) p
LEFT OUTER JOIN (
SELECT tpo.name, tpo.city, pt.type AS petType
FROM tbl_pet_owners tpo
LEFT OUTER JOIN tbl_pet_types tpt ON tpo.pet = tpt.pet
) po ON p.petType = po.petType
。
{{1}}
我没有MySQL机器来测试这个,但像这样的东西应该为你提供你想要的东西。