2012-03-28 63 views
2

我想提取與我的兩個數據集中存在的股票相對應的數據(在下面的代碼中給出)。Python中的sqlite3交集

這是我的數據:

#(stock,price,recommendation) 
my_data_1 = [('a',1,'BUY'),('b',2,'SELL'),('c',3,'HOLD'),('d',6,'BUY')] 

#(stock,price,volume) 
my_data_2 = [('a',1,5),('d',6,6),('e',2,7)] 

這裏是我的問題:

問題1:

我試圖提取的價格,推薦和體積對應於資產 'A' 。我非常希望得到這樣一個元組:

(u'a',1,u'BUY',5) 

問題2:

如果我想獲得交集的所有股票(不只是「一」的問題1),在此如果是庫存「a」和庫存「d」,那麼我的期望輸出變爲:

(u'a',1,u'BUY',5) 
(u'd',6,u'BUY',6) 

我應該怎麼做?

這是我嘗試(問題1):

import sqlite3 

my_data_1 = [('a',1,'BUY'),('b',2,'SELL'),('c',3,'HOLD'),('d',6,'BUY')] 

my_data_2 = [('a',1,5),('d',6,6),('e',2,7)] 

#I am using :memory: because I want to experiment 
#with the database a lot 

conn = sqlite3.connect(':memory:') 

c = conn.cursor() 

c.execute('''CREATE TABLE MY_TABLE_1 
      (stock TEXT, price REAL, recommendation TEXT)''') 

c.execute('''CREATE TABLE MY_TABLE_2 
      (stock TEXT, price REAL, volume REAL)''') 



for ele in my_data_1: 
    c.execute('''INSERT INTO MY_TABLE_1 VALUES(?,?,?)''',ele) 

for ele in my_data_2: 
    c.execute('''INSERT INTO MY_TABLE_2 VALUES(?,?,?)''',ele)  

conn.commit() 

# The problem is with the following line: 

c.execute('select* from my_table_1 where stock = ? INTERSECT select* from my_table_2 where stock = ?',('a','a') ) 

for entry in c: 
    print entry 

我沒有得到任何錯誤,也沒有輸出,這樣的東西是清楚了。

我也試過這條線:

c.execute('select* from my_table_1 where stock = ? INTERSECT select volume from my_table_2 where stock = ?',('a','a') 

,但它不工作,我得到這個錯誤:

c.execute('select* from my_table_1 where stock = ? INTERSECT select volume from my_table_2 where stock = ?',('a','a') ) 
sqlite3.OperationalError: SELECTs to the left and right of INTERSECT do not have the same number of result columns 

我明白爲什麼我會有不同數量造成的列,但不要」很明顯,爲什麼會觸發一個錯誤。

我該怎麼做?

非常感謝您提前

回答

5

看起來這兩個問題實際上是同一個問題。

爲什麼你的查詢不起作用:讓我們重新格式化查詢。

 
SELECT * FROM my_table_1 WHERE stock=? 
INTERSECT 
SELECT volume FROM my_table_2 WHERE stock=? 

有在交叉路口查詢,

  1. SELECT * FROM my_table_1 WHERE stock=?
  2. SELECT volume FROM my_table_2 WHERE stock=?

的 「相交」 的含義是 「給我,是兩個查詢行」 。如果查詢具有不同數量的列,則這沒有任何意義,因爲任何行都不可能出現在兩個查詢中。

請注意,SELECT volume FROM my_table_2不是一個非常有用的查詢,因爲它不會告訴您該卷屬於哪個庫存。查詢會給你類似{100, 15, 93, 42}

你實際上要做的:你想加入。

 
SELECT my_table_1.stock, my_table_2.price, recommendation, volume 
    FROM my_table_1 
    INNER JOIN my_table_2 ON my_table_1.stock=my_table_2.stock 
    WHERE stock=? 

認爲join是「將一個表中的行粘合到另一個表中的行上,從而將數據從一個行中的兩個表中提取出來。

這是奇怪的,價格出現在兩個表中;當您用連接編寫查詢時,您必須決定是要my_table_1.price還是my_table_2.price,或者您是否想加入my_table_1.price=my_table_2.price。你可能想考慮重新設計你的模式,這樣不會發生,它可能會讓你的生活更輕鬆。

+0

非常感謝您的回答;它完全符合我的要求。另外,謝謝你的解釋,我需要那:)。 – Akavall 2012-03-28 17:52:57

2

您對如何關聯不同表格有所誤解。

爲了做到這一點的最簡單的方法是用合適的條件加入其中,導致的結果自動地包括來自連接表中的數據。在下面的例子中,我選擇了所有的列,但是你當然可以通過在FROM子句中命名它們來選擇你想要的列。您還可以僅使用WHERE子句中的(a)更多條件選擇所需的那些行。當你執行你的代碼,請嘗試以下操作:

>>> c.execute("select * from my_table_1 t1 JOIN my_table_2 t2 ON t1.stock=t2.stock") 
<sqlite3.Cursor object at 0x1004608f0> 

這告訴SQLite的,從表1中採取行和錶行加入他們2次會議ON子句(的條件下,它們必須有相同的STOCK屬性值)。由於您選擇了這樣長的表名,並且因爲我是一個糟糕的打字員,所以我在FROM子句中使用了表格聲明以允許我在查詢的其餘部分使用縮短的名稱。

>>> c.fetchall() 

然後給你結果

[(u'a', 1.0, u'BUY', u'a', 1.0, 5.0), (u'd', 6.0, u'BUY', u'd', 6.0, 6.0)] 

這似乎回答這兩個1)和2)。對於STOCK的特定值,只需向查詢字符串中添加

WHERE t1.STOCK = 'a' -- or other required value, naturally 

。你可以看到通過查詢光標的描述屬性返回的列的名稱:

>>> [d[0] for d in c.description] 
['stock', 'price', 'recommendation', 'stock', 'price', 'volume'] 

相交操作用於從兩個獨立的SELECT查詢採取輸出和返回僅發生在這兩個元素。我認爲這不會有幫助。您遇到錯誤的原因是因爲查詢必須是「UNION兼容的」,也就是說它們在相交查詢中需要相同的數量和類型的列。