使用 Set 运算符查询以显示特定列
Query to display specific columns using a Set operator
我正在尝试使用 Set 运算符来显示没有城市名称(Table A col.)的国家名称(Table B col.)和没有国家名称(A)的城市名称(B) ).我还尝试使用 LEFT JOINS 编写此查询,如下所示,我包括 Table C(Regions) 因为我不确定是否在 LEFT JOIN 中使用该主键。
Table A(国家/地区):
Column_name | Column_id
|
COUNTRY_ID | 1
COUNTRY_NAME | 2
REGION_ID | 3
Table B(位置):
Column_name | Column_id
|
LOCATION_ID | 1
CITY | 4
COUNTRY_ID | 6
Table C(地区):
Column_name | Column_id
|
REGION_ID | 1
我试过以下方法:
SELECT c.country_name, l.city
FROM Countries c
LEFT JOIN Locations l ON c.country_id = l.country_id
UNION
SELECT c2.country_name, l2.city
FROM Countries c2
LEFT JOIN Locations l2 ON c2.country_id = l2.country_id;
上面的SQL语句返回了所有Table A值,Table A值不包含Table B值(没有城市的国家) .
我也试过下面这个语句,得到了完全相同的结果:
SELECT c.country_name, l.city
FROM Countries c
LEFT JOIN Locations l ON c.country_id = l.country_id
LEFT JOIN Regions r ON r.region_id = c.region_id;
它缺少的一件事是 Table 在 Table B 中找不到值(在城市中找不到国家。)
有很多选项可以获得您想要的结果。一种方法是使用 LEFT JOIN
获取没有城市的国家和 RIGHT JOIN
获取没有国家的城市:
SELECT c.country_name, l.city
FROM countries c
LEFT JOIN locations l ON c.country_id = l.country_id
WHERE l.city IS NULL
UNION ALL
SELECT c.country_name, l.city
FROM countries c
RIGHT JOIN locations l ON c.country_id = l.country_id
WHERE c.country_name IS NULL;
另一种可能是使用两个LEFT JOIN
,但是从相反的table开始,像这样:
SELECT c.country_name, l.city
FROM countries c
LEFT JOIN locations l ON c.country_id = l.country_id
WHERE l.city IS NULL
UNION ALL
SELECT c.country_name, l.city
FROM locations l
LEFT JOIN countries c ON c.country_id = l.country_id
WHERE c.country_name IS NULL;
如果您根本不喜欢使用 JOIN
,您可以使用 NOT IN
:
SELECT c.country_name, NULL city
FROM countries c
WHERE country_id NOT IN (SELECT country_id FROM locations)
UNION ALL
SELECT NULL country_name, l.city
FROM locations l
WHERE country_id NOT IN (SELECT country_id FROM countries);
或者,如果您更喜欢 NOT EXISTS
,这也行得通:
SELECT c.country_name, NULL city
FROM countries c
WHERE NOT EXISTS (SELECT 1 FROM locations WHERE country_id = c.country_id)
UNION ALL
SELECT NULL country_name, l.city
FROM locations l
WHERE NOT EXISTS (SELECT 1 FROM countries WHERE country_id = l.country_id);
我创建了一个示例,显示所有这些查询将产生相同的结果:db<>fiddle
将 ORDER BY c.country_name
和 ORDER BY l.city
添加到查询中,以防您希望结果集按它们排序。
最后但重要的注意事项:如您所见,我使用 UNION ALL
而不是 UNION
因为我看不出在您的用例中使用 UNION
的原因. UNION ALL
快得多,所以我建议使用它,除非有真正令人信服的理由不使用它。 UNION
的唯一优点是它不会显示重复的行,但我认为它们在您的情况下不太可能,因此不应该是必需的。
使用集合运算符查找没有城市的国家/地区的最简单示例是:
select country_id from countries
minus
select country_id from locations
COUNTRY_ID
----------
1
4
因为需要国名,所以查一下就可以了:
select country_name from countries
minus
select c.country_name from locations l
join countries c on c.country_id = l.country_id;
COUNTRY_NAME
-----------------
England
Italy
没有国家(或国家代码无效)的城市作为左连接和过滤器更简单:
select l.city, l.country_id
from locations l
left join countries c on c.country_id = l.country_id
where c.country_id is null
CITY
-----------------
Berlin
Tokyo
如果确实需要使用集合运算符来执行此操作,您将(从概念上)查找其 country_id 在(位置国家/地区减去城市国家/地区)集合中的城市:
select l.location_id, l.city, l.country_id
from locations l
where l.country_id in
( select country_id from locations
minus
select country_id from countries )
但是,这不会为您提供 country_id 为空的位置。
我正在尝试使用 Set 运算符来显示没有城市名称(Table A col.)的国家名称(Table B col.)和没有国家名称(A)的城市名称(B) ).我还尝试使用 LEFT JOINS 编写此查询,如下所示,我包括 Table C(Regions) 因为我不确定是否在 LEFT JOIN 中使用该主键。
Table A(国家/地区):
Column_name | Column_id
|
COUNTRY_ID | 1
COUNTRY_NAME | 2
REGION_ID | 3
Table B(位置):
Column_name | Column_id
|
LOCATION_ID | 1
CITY | 4
COUNTRY_ID | 6
Table C(地区):
Column_name | Column_id
|
REGION_ID | 1
我试过以下方法:
SELECT c.country_name, l.city
FROM Countries c
LEFT JOIN Locations l ON c.country_id = l.country_id
UNION
SELECT c2.country_name, l2.city
FROM Countries c2
LEFT JOIN Locations l2 ON c2.country_id = l2.country_id;
上面的SQL语句返回了所有Table A值,Table A值不包含Table B值(没有城市的国家) .
我也试过下面这个语句,得到了完全相同的结果:
SELECT c.country_name, l.city
FROM Countries c
LEFT JOIN Locations l ON c.country_id = l.country_id
LEFT JOIN Regions r ON r.region_id = c.region_id;
它缺少的一件事是 Table 在 Table B 中找不到值(在城市中找不到国家。)
有很多选项可以获得您想要的结果。一种方法是使用 LEFT JOIN
获取没有城市的国家和 RIGHT JOIN
获取没有国家的城市:
SELECT c.country_name, l.city
FROM countries c
LEFT JOIN locations l ON c.country_id = l.country_id
WHERE l.city IS NULL
UNION ALL
SELECT c.country_name, l.city
FROM countries c
RIGHT JOIN locations l ON c.country_id = l.country_id
WHERE c.country_name IS NULL;
另一种可能是使用两个LEFT JOIN
,但是从相反的table开始,像这样:
SELECT c.country_name, l.city
FROM countries c
LEFT JOIN locations l ON c.country_id = l.country_id
WHERE l.city IS NULL
UNION ALL
SELECT c.country_name, l.city
FROM locations l
LEFT JOIN countries c ON c.country_id = l.country_id
WHERE c.country_name IS NULL;
如果您根本不喜欢使用 JOIN
,您可以使用 NOT IN
:
SELECT c.country_name, NULL city
FROM countries c
WHERE country_id NOT IN (SELECT country_id FROM locations)
UNION ALL
SELECT NULL country_name, l.city
FROM locations l
WHERE country_id NOT IN (SELECT country_id FROM countries);
或者,如果您更喜欢 NOT EXISTS
,这也行得通:
SELECT c.country_name, NULL city
FROM countries c
WHERE NOT EXISTS (SELECT 1 FROM locations WHERE country_id = c.country_id)
UNION ALL
SELECT NULL country_name, l.city
FROM locations l
WHERE NOT EXISTS (SELECT 1 FROM countries WHERE country_id = l.country_id);
我创建了一个示例,显示所有这些查询将产生相同的结果:db<>fiddle
将 ORDER BY c.country_name
和 ORDER BY l.city
添加到查询中,以防您希望结果集按它们排序。
最后但重要的注意事项:如您所见,我使用 UNION ALL
而不是 UNION
因为我看不出在您的用例中使用 UNION
的原因. UNION ALL
快得多,所以我建议使用它,除非有真正令人信服的理由不使用它。 UNION
的唯一优点是它不会显示重复的行,但我认为它们在您的情况下不太可能,因此不应该是必需的。
使用集合运算符查找没有城市的国家/地区的最简单示例是:
select country_id from countries
minus
select country_id from locations
COUNTRY_ID
----------
1
4
因为需要国名,所以查一下就可以了:
select country_name from countries
minus
select c.country_name from locations l
join countries c on c.country_id = l.country_id;
COUNTRY_NAME
-----------------
England
Italy
没有国家(或国家代码无效)的城市作为左连接和过滤器更简单:
select l.city, l.country_id
from locations l
left join countries c on c.country_id = l.country_id
where c.country_id is null
CITY
-----------------
Berlin
Tokyo
如果确实需要使用集合运算符来执行此操作,您将(从概念上)查找其 country_id 在(位置国家/地区减去城市国家/地区)集合中的城市:
select l.location_id, l.city, l.country_id
from locations l
where l.country_id in
( select country_id from locations
minus
select country_id from countries )
但是,这不会为您提供 country_id 为空的位置。