列引用含糊不清
Ambiguity with column reference
我尝试运行一个简单的代码如下:
Create Table weather (
city varchar(80),
temp_lo int,
temp_hi int,
prcp real,
date date
);
Insert Into weather Values ('A', -5, 40, 25, '2018-01-10');
Insert Into weather Values ('B', 5, 45, 15, '2018-02-10');
Create Table cities (
city varchar(80),
location point
);
Insert Into cities Values ('A', '(12,10)');
Insert Into cities Values ('B', '(6,4)');
Insert Into cities Values ('C', '(18,13)');
Select * From cities, weather Where city = 'A'
但我得到的是
ERROR: column reference "city" is ambiguous.
我的代码有什么问题?
tables cities
和 weather
都有一个名为 city
的列。在您的 WHERE
子句中,您过滤了 city = 'A'
,它指的是 table 的 city
?
您可以通过在列前加上 table 名称来告诉引擎您要过滤哪一个:
Select * From cities, weather Where cities.city = 'A'
您也可以使用别名引用 tables:
Select *
From cities AS C, weather AS W
Where C.city = 'A'
但最重要的是,确保您 将 table 连接在一起 ,除非您希望两个 table 的所有记录无条件匹配(笛卡尔积)。您可以使用显式 INNER JOIN
:
加入它们
Select
*
From
cities AS C
INNER JOIN weather AS W ON C.city = W.city
Where
C.city = 'A'
在您提到的示例中,使用了此查询:
SELECT *
FROM weather, cities
WHERE city = name;
但是在这里,cities
table 有 name
列(而不是 你 使用的 city
).所以这个 WHERE
子句将 weather
和 cities
table 链接在一起,因为 city
是 weather
列而 name
是 cities
列并且没有歧义,因为两列的名称不同。
如果我是你,我的模型会略有不同。
为了使事情稍微正常化,我们将从城市 table 开始并进行一些更改:
create table cities (
city_id integer primary key,
city_name varchar(100),
location point
);
请注意,我使用了一个整数来表示table的ID和主键,并单独存储了城市名称。这为您提供了一个很好的易于维护的查找 table。通过使用整数作为主键,我们在存储数据时也会使用 less space in the weather table
Create Table weather (
city_id integer,
temp_lo int,
temp_hi int,
prcp real,
record_date date
);
请注意,我存储的是城市的 ID 而不是名称。另外,我重命名了 date
,因为在 SQL reserved words.
之后命名列不是一个好主意
确保我们在测试数据中使用 ID:
Insert Into weather Values (1, -5, 40, 25, '2018-01-10');
Insert Into weather Values (2, 5, 45, 15, '2018-02-10');
Insert Into cities Values (1,'A', '(12,10)');
Insert Into cities Values (2,'B', '(6,4)');
Insert Into cities Values (3,'C', '(18,13)');
您的旧查询:
Select * From cities, weather Where city = 'A'
名称不明确,因为两个 table 都有一个 city
列,并且数据库引擎不知道您指的是哪个 city
(它不会自动知道是否它需要使用 cities.city 或 weather.city)。该查询还执行 cartesian product,因为您尚未将 table 连接在一起。
使用我在上面所做的更改,您需要如下内容:
Select *
From cities, weather
Where cities.city_id = weather.city_id
and city_name = 'A';
或者,使用更新的连接语法:
Select *
From cities
join weather on cities.city_id = weather.city_id
Where city_name = 'A';
这两个查询在功能上是等价的 - 现在大多数人更喜欢第二个查询,因为它可以防止错误(例如:忘记实际加入 where
子句)。
我尝试运行一个简单的代码如下:
Create Table weather (
city varchar(80),
temp_lo int,
temp_hi int,
prcp real,
date date
);
Insert Into weather Values ('A', -5, 40, 25, '2018-01-10');
Insert Into weather Values ('B', 5, 45, 15, '2018-02-10');
Create Table cities (
city varchar(80),
location point
);
Insert Into cities Values ('A', '(12,10)');
Insert Into cities Values ('B', '(6,4)');
Insert Into cities Values ('C', '(18,13)');
Select * From cities, weather Where city = 'A'
但我得到的是
ERROR: column reference "city" is ambiguous.
我的代码有什么问题?
tables cities
和 weather
都有一个名为 city
的列。在您的 WHERE
子句中,您过滤了 city = 'A'
,它指的是 table 的 city
?
您可以通过在列前加上 table 名称来告诉引擎您要过滤哪一个:
Select * From cities, weather Where cities.city = 'A'
您也可以使用别名引用 tables:
Select *
From cities AS C, weather AS W
Where C.city = 'A'
但最重要的是,确保您 将 table 连接在一起 ,除非您希望两个 table 的所有记录无条件匹配(笛卡尔积)。您可以使用显式 INNER JOIN
:
Select
*
From
cities AS C
INNER JOIN weather AS W ON C.city = W.city
Where
C.city = 'A'
在您提到的示例中,使用了此查询:
SELECT *
FROM weather, cities
WHERE city = name;
但是在这里,cities
table 有 name
列(而不是 你 使用的 city
).所以这个 WHERE
子句将 weather
和 cities
table 链接在一起,因为 city
是 weather
列而 name
是 cities
列并且没有歧义,因为两列的名称不同。
如果我是你,我的模型会略有不同。
为了使事情稍微正常化,我们将从城市 table 开始并进行一些更改:
create table cities (
city_id integer primary key,
city_name varchar(100),
location point
);
请注意,我使用了一个整数来表示table的ID和主键,并单独存储了城市名称。这为您提供了一个很好的易于维护的查找 table。通过使用整数作为主键,我们在存储数据时也会使用 less space in the weather table
Create Table weather (
city_id integer,
temp_lo int,
temp_hi int,
prcp real,
record_date date
);
请注意,我存储的是城市的 ID 而不是名称。另外,我重命名了 date
,因为在 SQL reserved words.
确保我们在测试数据中使用 ID:
Insert Into weather Values (1, -5, 40, 25, '2018-01-10');
Insert Into weather Values (2, 5, 45, 15, '2018-02-10');
Insert Into cities Values (1,'A', '(12,10)');
Insert Into cities Values (2,'B', '(6,4)');
Insert Into cities Values (3,'C', '(18,13)');
您的旧查询:
Select * From cities, weather Where city = 'A'
名称不明确,因为两个 table 都有一个 city
列,并且数据库引擎不知道您指的是哪个 city
(它不会自动知道是否它需要使用 cities.city 或 weather.city)。该查询还执行 cartesian product,因为您尚未将 table 连接在一起。
使用我在上面所做的更改,您需要如下内容:
Select *
From cities, weather
Where cities.city_id = weather.city_id
and city_name = 'A';
或者,使用更新的连接语法:
Select *
From cities
join weather on cities.city_id = weather.city_id
Where city_name = 'A';
这两个查询在功能上是等价的 - 现在大多数人更喜欢第二个查询,因为它可以防止错误(例如:忘记实际加入 where
子句)。