2012-03-28 32 views
2

Ich versuche, Daten zu extrahieren, die einer Aktie entspricht, die in meinen beiden Datensätzen vorhanden ist (in einem Code unten angegeben).Kreuzung in sqlite3 in Python

Dies ist meine Daten:

#(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)] 

Hier sind meine Fragen:

Frage 1:

Ich versuche, Preis, Empfehlung und Volumen zu extrahieren, die auf Asset entsprechen 'a' . Im Idealfall würde Ich mag ein Tupel wie folgt erhalten:

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

Frage 2:

Was passiert, wenn ich wollte Kreuzung erhalten für alle Bestände (nicht nur ‚a‘ wie in Frage 1), in dieser Fall ist es Lager ‚a‘, und Lager ‚d‘ ist, dann meine gewünschte Ausgabe wird:

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

Wie soll ich das tun?

Hier ist mein Versuch (Frage 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 

ich keine Fehler, aber auch keine Ausgabe, so klar aus etwas ist.

Ich habe auch versucht, diese Zeile:

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

aber es funktioniert nicht, bekomme ich diesen Fehler:

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 

Ich verstehe, warum ich unterschiedliche Anzahl von resultierenden Spalten haben würde, aber don‘ Ich verstehe nicht, warum das einen Fehler auslöst.

Wie soll ich das tun?

Vielen Dank im Voraus

Antwort

5

Es sieht aus wie diese beiden Fragen wirklich die gleiche Frage sind.

Warum Ihre Abfrage nicht funktioniert: Lassen Sie uns die Abfrage neu formatieren.

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

Es gibt zwei Abfragen in der Kreuzung,

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

Die Bedeutung von "schneiden" ist "Gib mir die Zeilen, die in beiden Abfragen sind" . Das macht keinen Sinn, wenn die Abfragen eine andere Anzahl von Spalten haben, da es unmöglich ist, dass eine Zeile in beiden Abfragen erscheint.

Beachten Sie, dass SELECT volume FROM my_table_2 keine sehr nützliche Abfrage ist, da es Ihnen nicht mitteilt, zu welchem ​​Bestand das Volumen gehört. Die Abfrage gibt Ihnen etwas wie {100, 15, 93, 42}.

Was Sie eigentlich versuchen zu tun: Sie wollen ein Join.

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

Stellen Sie sich verbinden, wie „die Zeilen von einer Tabelle auf die Reihen von einer anderen Tabelle Leim, Daten aus beiden Tabellen in einer einzigen Reihe zu geben.“

Es ist seltsam, dass der Preis in beiden Tabellen erscheint; Wenn Sie die Abfrage mit dem Join schreiben, müssen Sie entscheiden, ob Sie my_table_1.price oder my_table_2.price möchten, oder ob Sie auf beitreten möchten. Vielleicht sollten Sie in Erwägung ziehen, Ihr Schema neu zu gestalten, damit dies nicht geschieht. Es könnte Ihnen das Leben erleichtern.

+0

Vielen Dank für Ihre Antwort; es macht genau das, wonach ich gesucht habe. Danke auch für die Erklärung, ich brauchte das :). – Akavall

2

Sie leiden unter einem Missverständnis darüber, wie verschiedene Tabellen korreliert werden.

Um dies zu tun, ist der einfachste Weg, sie mit einer geeigneten Bedingung zu verbinden, was zu Ergebnissen führt, die automatisch die Daten aus den beiden verbundenen Tabellen enthalten. Im Beispiel unten wähle ich alle Spalten aus, aber Sie können natürlich nur die gewünschten auswählen, indem Sie sie in der FROM-Klausel benennen. Sie können auch nur die gewünschten Zeilen mit (a) weiteren Bedingungen in einer WHERE-Klausel auswählen. Nachdem Sie Ihren Code ausführen, versuchen Sie Folgendes:

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

Diese SQLite Reihen von Tisch zu nehmen erzählt 1 und verbinden sie mit Zeilen in der Tabelle 2, die die Voraussetzungen in der ON-Klausel (dh sie haben die haben gleicher Wert für ihr STOCK-Attribut). Da Sie so lange Tabellennamen gewählt haben und weil ich eine beschissene Schreibkraft bin, habe ich in der FROM-Klausel Tabellen-Alices verwendet, um im Rest der Abfrage verkürzte Namen verwenden zu können.

>>> c.fetchall() 

gibt Ihnen dann das Ergebnis

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

, die sowohl 1 zu beantworten scheint) und 2). Für nur einen bestimmten Wert von STOCK einfach

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

zu der Abfragezeichenfolge hinzufügen. Sie können die Namen der Spalten zurückgegeben sehen durch die Beschreibung Attribut des Cursors Abfrage:

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

Die INTERSECT-Vorgang verwendet wird, um die Ausgaben von zwei separaten SELECT-Abfragen zu nehmen und nur diejenigen Elemente zurück, die in beiden auftreten. Ich denke nicht, dass das hier hilfreich ist. Der Grund für den Fehler liegt darin, dass die Abfragen "UNION-kompatibel" sein müssen, dh sie müssen die gleiche Anzahl und den gleichen Typ von Spalten in den durchschnittenen Abfragen haben.