2012-03-28 3 views
2

Я пытаюсь извлечь данные, которые соответствуют запасу, который присутствует в обоих моих наборах данных (данный в коде ниже).Пересечение в sqlite3 в Python

Это мои данные:

#(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:

Я пытаюсь извлечь цену, рекомендацию, и объем, которые соответствуют актив 'а' , В идеале я хотел бы получить кортеж так:

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

Вопрос 2:

Что делать, если я хотел бы получить пересечение всех акций (а не только «а», как и в вопросе 1), в этом случае это акции «а» и ЗАО «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 

Я понимаю, почему я хотел бы иметь разное количество результирующих столбцов, но дон» t почему бы не вызвать ошибку.

Как мне это сделать?

Спасибо заранее

ответ

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=? 

Придумайте присоединиться в качестве «склеить строки из одной таблицы на строки из другой таблицы, давая данные из обеих таблиц в одной строке.»

Странно, что цена указана в обеих таблицах; когда вы пишете запрос с соединением, вы должны решить, хотите ли вы my_table_1.price или my_table_2.price, или хотите присоединиться к my_table_1.price=my_table_2.price. Вы можете захотеть перепроектировать схему, чтобы этого не произошло, это может сделать вашу жизнь проще.

+0

Большое спасибо за ваш ответ; он делает именно то, что я искал. Кроме того, спасибо за объяснение, мне это нужно :). – Akavall

2

Вы страдаете от недоразумений относительно того, как соотнести различные таблицы.

Для этого самым простым способом является СОЕДИНЕНИЕ их с подходящим условием, в результате чего результаты автоматически включаются в данные из объединенных таблиц. В приведенном ниже примере я выбираю все столбцы, но вы можете, конечно, выбирать только те, которые вы хотите, называя их в предложении FROM. Вы также можете выбрать только те строки, в которых хотите (a) дальнейшее условие (условия) в предложении WHERE. После выполнения вам кода, попробуйте следующее:

>>> 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). Поскольку вы выбрали такие длинные имена таблиц, и потому, что я дрянная машинистка, я использовал table alises в предложении 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'] 

Операция INTERSECT используется для отбора выходов из двух отдельных запросов SELECT, и возвращать только те элементы, которые происходят в обеих. Я не думаю, что здесь будет полезно. Причина, по которой вы получили сообщение об ошибке, состоит в том, что запросы должны быть совместимы с UNION, что означает, что они нуждаются в том же количестве и типе столбцов в пересекающихся запросах.

Смежные вопросы