如何从另一个表中插入到另一个表的新表中

时间:2016-09-29 05:44:50

标签: python sqlite

我正在使用Python和SQLite来操作数据库。

我在数据库Movies中有一个SQLite表Data,如下所示:

| ID             | Country     
+----------------+-------------
| 1              | USA, Germany, Mexico 
| 2              | Brazil, Peru
| 3              | Peru

我在同一个数据库中有一个表Countries,看起来像这个

| ID             | Country     
+----------------+-------------
| 1              | USA
| 1              | Germany
| 1              | Mexico
| 2              | Brazil
| 2              | Peru
| 3              | Peru

我想从数据库Data将所有来自秘鲁的电影插入到一个看起来像这样的新数据库PeruData

| ID             | Country     
+----------------+-------------
| 2              | Peru
| 3              | Peru

我是SQL新手,无法编写正确的查询。

这是我的尝试:

con = sqlite3.connect("PeruData.db")
cur = con.cursor()

cur.execute("CREATE TABLE Movies (ID, Country);")
cur.execute("ATTACH DATABASE 'Data.db' AS other;")
cur.execute("\
        INSERT INTO Movies \
        (ID, Country) \
        SELECT ID, Country
        FROM other.Movies CROSS JOIN other.Countries\
        WHERE other.Movies.ID = other.Countries.ID AND other.Countries.Country = 'Peru'\

con.commit()
con.close()

显然,我做错了,因为我收到了错误

  

sqlite3.OperationalError:没有这样的表:other.Countries

2 个答案:

答案 0 :(得分:0)

这是一种成功获得所需结果的解决方法。

您不必编写con = sqlite3.connect("data.db")然后必须编写con.commit()con.close(),而是可以将代码缩短为以下内容:

with sqlite3.connect("Data.db") as connection:
    c = connection.cursor()

这样,您不必每次使用数据库时都提交更改并关闭。这是我学到的一条漂亮的捷径。现在你的代码......

就个人而言,我不熟悉SQL语句 ATTACH DATABASE 。我会将您的新数据库合并到程序的 end 中,这样就可以避免任何您不了解处理的冲突(例如给出的OperationalError)。首先,我将开始获得所需的结果,然后将其插入到新表中。您的第三个执行语句可以像这样重写:

c.execute("""SELECT DISTINCT Movies.ID, Countries.Country
        FROM Movies
        CROSS JOIN Countries
        WHERE Movies.ID = Countries.ID AND Countries.Country = 'Peru'
        """)

这可以完成这项工作,但您需要使用 fetchall()将结果集返回到元组列表中,然后可以将其插入到新表中。所以你输入这个:

rows = c.fetchall()

现在,您可以通过创建“PeruData.db”数据库,创建表格以及插入值来打开新连接。

with sqlite3.connect("PeruData.db") as connection:
    c = connection.cursor()

    c.execute("CREATE TABLE Movies (ID INT, Country TEXT)")
    c.executemany("INSERT INTO Movies VALUES(?, ?)", rows)

就是这样。 希望我能回答你的问题!

答案 1 :(得分:0)

当前错误可能是由错字或其他小问题引起的。我可以创建这里描述的数据库,并在修复次要错误后成功执行插入:在行尾添加反斜杠并为所选列添加限定符。

但我也建议你在多表选择中为表使用别名。在我的测试中起作用的代码是:

void getChildren(int pid, levels){

    if(levels==0) return Collection.emptyList();

    List<ParantCategory> results = al.stream().filter(
            p->p.getPid()==pid
        ).collect(Collectors.toList());
    for(ParantCategory p: results){
        results.addAll(getChildren(p.getPid(), levels-1));
    }
    return results;
}