2010-05-31 99 views
3

使用sqlite3的標準庫,下面的查詢工作正常的sqlite3的命令行:蟒蛇sqlite3的將不執行加入,但在Python 2.6.4 sqlite3的單獨會

select segmentid, node_t, start, number,title from 
    ((segments inner join position using (segmentid)) 
    left outer join titles using (legid, segmentid)) 
    left outer join numbers using (start, legid, version); 

但是如果我通過執行它在Python sqlite3的圖書館中,我得到一個錯誤:

>>> conn=sqlite3.connect('data/test.db') 
>>> conn.execute('''select segmentid, node_t, start, number,title from 
((segments inner join position using (segmentid)) left outer join titles using 
(legid, segmentid)) left outer join numbers using (start, legid, version)''') 
Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
sqlite3.OperationalError: cannot join using column start - column not present 
in both tables 

的加入出現的左手側的(計算)表中有相關​​的列,因爲如果我自行檢查它,我得到:

>>> conn.execute('''select * from ((segments inner join position using 
(segmentid)) left outer join titles using 
(legid, segmentid)) limit 20''').description 
(('segmentid', None, None, None, None, None, None), ('html', None, None, None, 
None, None, None), ('node_t', None, None, None, None, None, None), ('legid', 
None, None, None, None, None, None), ('version', None, None, None, None, None, 
None), ('start', None, None, None, None, None, None), ('title', None, None, 
None, None, None, None)) 

我的模式是:

CREATE TABLE leg (legid integer primary key, t char(16), year char(16), 
    no char(16)); 
CREATE TABLE numbers (
    number char(16), legid integer, version integer, start integer, 
    end integer, prev integer, prev_number char(16), next integer, 
    next_number char(16), primary key (number, legid, version)); 
CREATE TABLE position (
    segmentid integer, legid integer, version integer, start integer, 
    primary key (segmentid, legid, version)); 
CREATE TABLE 'segments' 
    (segmentid integer primary key, html text, node_t integer); 
CREATE TABLE titles (legid integer, segmentid integer, title text, 
    primary key (legid, segmentid)); 
CREATE TABLE versions 
    (legid integer, version integer, primary key (legid, version)); 
CREATE INDEX idx_numbers_start on numbers (legid, version, start); 

我感到困惑,我在做什麼錯。我已經嘗試退出/重新啓動python和sqlite命令行,無法看到我做錯了什麼。這可能是完全明顯的。

+0

對於您的模式和頂部的原始查詢,我得到'錯誤:模棱兩可的列名:segmentid' – msw 2010-05-31 19:36:33

+0

這很令人費解。 USING關鍵字在結果表中合併給定的列名,所以不應該有歧義。哪個版本的sqlite3?正如我所說,使用它和命令行中的類似查詢沒有問題? – 2010-05-31 20:06:17

+0

請參閱下面的詳細信息... – msw 2010-05-31 20:14:32

回答

1

溶液(使用Python庫我的問題)似乎是引入一個完全虛假的表名是相同的:

SELECT legid, version, segmentid, html, node_t, start, number, title 
    from ((segments inner join position using (segmentid)) 
    left outer join titles using (legid, segmentid)) as LT 
    left outer join numbers using (start, legid, version); 

我認爲這樣做是強制sqlite收集最外層外連接的左側的名稱,其中之一是「開始」,然後給最外層的外連接進行操作。這對我很有用 - 可能是升級會引入更多問題而不是刪除它們,但是當它到達時我會穿過那座橋。

+0

我有類似的問題,我通過使用「on」而不是「使用」來解決它, – 2015-01-26 13:04:28

0

你有一個有趣的名字表:

CREATE TABLE 'segments' 

但我不認爲這是問題。每個請求,這是我與'segments'表重建爲segments你的查詢執行:

$ sqlite3 junk.sqlite 
SQLite version 3.6.22 
Enter ".help" for instructions 
Enter SQL statements terminated with a ";" 
sqlite> .schema 
CREATE TABLE leg (legid integer primary key, t char(16), year char(16), 
    no char(16)); 
CREATE TABLE numbers (
    number char(16), legid integer, version integer, start integer, 
    end integer, prev integer, prev_number char(16), next integer, 
    next_number char(16), primary key (number, legid, version)); 
CREATE TABLE position (
    segmentid integer, legid integer, version integer, start integer, 
    primary key (segmentid, legid, version)); 
CREATE TABLE segments (segmentid integer primary key, html text, node_t integer); 
CREATE TABLE titles (legid integer, segmentid integer, title text, 
    primary key (legid, segmentid)); 
CREATE TABLE versions 
    (legid integer, version integer, primary key (legid, version)); 
CREATE INDEX idx_numbers_start on numbers (legid, version, start); 
sqlite> select segmentid, node_t, start, number,title from 
    ...>  ((segments inner join position using (segmentid)) 
    ...>  left outer join titles using (legid, segmentid)) 
    ...>  left outer join numbers using (start, legid, version); 
Error: ambiguous column name: segmentid 
+0

複製粘貼您的模式到我的sqlite 3.4.0並運行完全相同的查詢不會給我一個錯誤。我不認爲它應該給出一個錯誤 - 除非我錯過了一些東西。你認爲它應該?這是3.4和3.6.22之間的差異嗎?我現在比我更困惑了。 – 2010-05-31 21:09:45

+0

對不起,這有負面的幫助。坦率地說,我用多重嵌套連接超出了我的深度,但是如果我不得不猜測,sqlite 3.6.22在語義上可能更「正確」 - 對於SQL而言可怕的歧義語言。不過,我並不是說你應該更喜歡它。 – msw 2010-05-31 21:49:25

0

SQLite的版本3.6.22 - 看起來像你需要限定「曖昧列名」 ...

sqlite> select segmentid, node_t, start, number,title from 
    ...> ((segments inner join position using (segmentid)) 
    ...> left outer join titles using (legid, segmentid)) 
    ...> left outer join numbers using (start, legid, version); 
Error: ambiguous column name: segmentid 

sqlite> select segments.segmentid, node_t, start, number,title from 
    ...> ((segments inner join position using (segmentid)) 
    ...> left outer join titles using (legid, segmentid)) 
    ...> left outer join numbers using (start, legid, version); 
Error: ambiguous column name: start 

sqlite> select segments.segmentid, node_t, numbers.start, number,title from 
    ...> ((segments inner join position using (segmentid)) 
    ...> left outer join titles using (legid, segmentid)) 
    ...> left outer join numbers using (start, legid, version); 
sqlite> 

行爲是使用SQLite版本3.6.23.1

+0

您使用的是哪個版本的sqlite?升級到它可能很有用。 – 2010-06-01 14:01:55

+0

@Francis,上面的例子是3.6.22 – 2010-06-01 15:51:34

+0

@Francis,上面的例子是3.6.22和3.6.23.1。 – 2010-06-01 16:03:42