我在使用ON
联接表达式语法从两个已连接表之间具有共享名称的子选择中选择列时遇到问题。
我有两个表event
和geography
,每个表都有一个geography_id
列,它是相同的数据类型,event.geography_id
是一个外键{ {1}}(地理位置提供有关活动的信息):
我遇到的问题是,当使用geography
语法加入这两个表时,我无法引用这两个表之间的共享列,但在使用ON
时它可以正常工作语法。
我意识到USING
的作用是因为它suppresses redundant columns,但由于该语句使用了许多不同的连接表,而且模式的更改频率更高,我宁愿尽可能明确。
我遇到问题的具体SQL是:
USING
出现错误:
错误:列引用" geography_id"含糊不清
第8行:(1,2,3)中的x.geography_id
我正在使用PostgreSQL 9.0.14。
答案 0 :(得分:4)
在SQL中,能够选择除之外的一个或多个明确要排除的列时,这将是一个非常有用的功能。如果它存在,您可以使用此功能通过排除g.geography_id
来解决您的问题。不幸的是,在任何DBMS中,这样的功能似乎都不存在。请参阅https://dba.stackexchange.com/questions/1957/sql-select-all-columns-except-some。
一个解决方案,如@a_horse_with_no_name所述,是列出您要选择的每一列,只省略您不想要的那些。
实际上还有另一种可能更好的解决方案,即选择*
和e.geography_id
,但将后者别名为另一个名称,该名称在子查询结果集中将是明确的。像这样:
select
x.event_id
from (
select *, e.geography_id geography_id1 from event e
left join geography g on (e.geography_id = g.geography_id)
) x
where
x.geography_id1 in (1,2,3)
答案 1 :(得分:0)
您可以将查询编写为:
select
e.event_id
from event e
left join geography g
on (e.geography_id = g.geography_id)
where
e.geography_id in (1,2,3)
这应该在逻辑上等效,或切换到:
where
g.geography_id in (1,2,3)
获得只有匹配的回报(这会问为什么不使用内部联接)
答案 2 :(得分:0)
在加入之前将谓词向下拉入子查询:
SELECT e.event_id
FROM (SELECT * FROM event WHERE geography_id IN (1,2,3)) e
LEFT JOIN geography g ON (g.geography_id = e.geography_id);
结果与原始查询100%相同:
SELECT e.event_id
FROM event e
LEFT JOIN geography g USING (geography_id)
WHERE geography_id in (1,2,3);
只是替代方案应该更快(尽早排除不相关的行)。对于变通方法来说,这是一个可接受的副作用。