使用NATURAL JOIN进行sqlite查询会产生额外的记录

时间:2016-03-26 01:22:38

标签: python pandas sqlite

我试图用Python查询我的SQLite数据库,希望将结果作为Pandas DataFrame返回。但是,查询中出现错误导致输出错误且记录太多的问题。例如,如果我使用此查询文本:

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")"

正确的结果应该是两行,一个是那个具有这些条件的玩家的每个外观。如果要从光标打印正确的结果,它将如下所示:

(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的数据库浏览器中,查询就能完美运行。

表的结构如下:

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) )

这是相关的pandas部分,但即使我只是打印光标结果(如上所示)也会出现问题。

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

1 个答案:

答案 0 :(得分: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')"""