我试图用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)
答案 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')"""