2016-03-26 13 views
1

結果をPandas DataFrameとして返すために、PythonでSQLiteデータベースをクエリしようとしています。しかし、クエリーで何かが間違っていて、レコードが多すぎると誤った出力が発生します。たとえば、次のクエリテキストを使用した場合:NATURAL JOINを使用したsqliteクエリで余分なレコードが生成される

query = "SELECT name, season, opponent, ratingA, ratingB 
    FROM players NATURAL JOIN games NATURAL JOIN A_ratings NATURAL JOIN B_ratings 
    WHERE (season="2015-16") AND (home_away="home") AND (tournament="tournX") AND (name="John Doe")" 

正しい結果は、その条件のプレーヤーの各外観ごとに1つずつ、2行にする必要があります。あなたはカーソルから正しい結果を印刷した場合、それは次のようになります。

(u'John Doe', u'2015-16', u'TeamAlpha', 7.5, 8.0) 
(u'John Doe', u'2015-16', u'TeamBeta', 6.0, 6.0) 

代わり、私は名前で、条件に一致するゲームのためのチームのすべてのプレーヤーのための評価を得ますname列に正しい名前を置き換えクエリから、次のように:

(u'John Doe', u'2015-16', u'TeamAlpha', 7.5, 8.0) 
(u'John Doe', u'2015-16', u'TeamAlpha', 8.5, 9.0) 
(u'John Doe', u'2015-16', u'TeamAlpha', 6.5, 7.0) 
(u'John Doe', u'2015-16', u'TeamAlpha', 6.5, 6.0) 
(u'John Doe', u'2015-16', u'TeamAlpha', 7.0, 7.0)) 
(u'John Doe', u'2015-16', u'TeamBeta', 6.0, 6.0) 
(u'John Doe', u'2015-16', u'TeamBeta', 8.0, 7.5) 
(u'John Doe', u'2015-16', u'TeamBeta', 7.0, 7.0) 
(u'John Doe', u'2015-16', u'TeamBeta', 7.5, 8.0) 
(u'John Doe', u'2015-16', u'TeamBeta', 6.5, 7.0) 

テーブル間に起こって乗算のいくつかの種類があるようだ、と私は問題がNATURALであると思い一部のJOINが、私はそれを修正する方法を把握することはできません。

私はSQL初心者ですが、明らかにSQLiteのDBブラウザに入力すると完全に動作するため、私は困惑しています。

テーブルはこのように構成されています。ここでは

CREATE TABLE "games" (
`gameID` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, 
`season` TEXT, 
`tournament` TEXT, 
`home_away` TEXT, 
`opponent` TEXT, ) 

CREATE TABLE "players" (
`playerID` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, 
`name` TEXT UNIQUE) 

CREATE TABLE "A_ratings" (
`A_ratingID` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, 
`playerID` INTEGER, 
`gameID` INTEGER, 
`ratingA` REAL, 
FOREIGN KEY(`playerID`) REFERENCES `players`(`playerID`), 
FOREIGN KEY(`gameID`) REFERENCES games(gameID)) 

CREATE TABLE "B_ratings" (
`B_ratingID` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, 
`playerID` INTEGER, 
`gameID` INTEGER, 
`ratingB` REAL, 
FOREIGN KEY(`playerID`) REFERENCES `players`(`playerID`), 
FOREIGN KEY(`gameID`) REFERENCES games(gameID)) 

は、関連するパンダの一部ですが、問題は、私はちょうど(上記のように)カーソルの結果を印刷する場合にも発生します。

cnxn = sqlite3.connect(path) 
df = pd.read_sql(query, cnxn) 

答えて

2

自然な結合から離れ、結合したい列に明示的に結合することをお勧めします。それは物事の推測を取ります。特にこのようなケースでは、明確な切り札ではありません。関連するものと直接関係のないテーブル(プレーヤーとゲーム)があるので、これら2つのテーブルの間に定格表を含まない自然な結合はありません。それらの結合が行われる順序に応じて、そこではクロス結合(乗算)が行われる可能性があります。合併症にわずかに加わることは、A_ratingとB_ratingの両方がゲームと選手の両方に独自のジョインを持つことである。

あなたのデータの多くを見ることなく、私は一種のあなたが参加し、私はこの試みのようなもの与えるだろう、自然から一つのケースでは、あなたの望ましい結果を得ているという事実に基づいて推測している:

query = """SELECT 
       name, season, opponent, ratingA, ratingB 
      FROM players 
       inner join A_ratings on 
       players.playerID = A_ratings.playerID 
       inner join B_ratings on 
       A_ratings.playerID = B_ratings.playerID and A_ratings.gameID = B_ratings.gameID 
       inner join games on 
        B_ratings.gameID = games.gameID 
      WHERE (season='2015-16') AND 
       (home_away='home') AND 
       (tournament='tournX') AND 
       (name='John Doe')""" 
+0

USINGを使用すると、結合がより簡単になります。 –

+0

ありがとう。私は結合の順序が重要であることを知らなかった。私はそれが私の試みた解決策が私に失敗した理由だと思う。 – jdep

関連する問題