2015-03-30 50 views
3

我在使用ON連接表達式語法從兩個連接表之間共享名稱的子查詢中選擇一列時遇到問題。解決子查詢中模糊列的問題

我有兩個表,eventgeography的每一個具有一個geography_id柱,這是相同的數據類型,和event.geography_id爲外鍵入geography(地理提供關於事件的信息):

simplified ERD from Dia

我遇到的問題是,當使用ON語法加入它們時,我無法引用這兩個表格之間的共享列,但它在使用USING語法時有效。

我意識到USING的作品,因爲它suppresses redundant columns,但自言使用許多不同的連接表與多不經常改變的模式,我寧願儘可能明確。

我遇到問題的特定SQL是:

select 
    x.event_id 
from (
    select * from event e 
    left join geography g on (e.geography_id = g.geography_id) 
) x 
where 
    x.geography_id in (1,2,3) 

這給錯誤:

ERROR: column reference "geography_id" is ambiguous

LINE 8: x.geography_id in (1,2,3)

我使用PostgreSQL 9.0.14。

+1

您需要在派生表中單獨列出每個列(子選擇)。這是'使用'條款的唯一選擇。 – 2015-03-30 21:32:36

回答

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) 
+0

這是最乾淨的解決方案,也是唯一不涉及重構整個查詢的解決方案。 – amphetamachine 2015-04-01 14:43:48

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) 

得到回報,只有有比賽(這會問爲什麼不使用內部連接)

+0

無法使用內部聯接,因爲'geography_id' where子句是可選的(如果未指定,返回所有事件,而不管它們是否具有地理位置),並且「x.geography_id爲null」也是可能的子句。 – amphetamachine 2015-03-30 21:51:58

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); 

只是,替代要快很多(早期排除不相關的行)。解決方法相當可接受的副作用。