【问题标题】:How insert into a new table from another table cross joined with another table如何从另一个表插入新表与另一个表交叉连接
【发布时间】:2016-09-29 16:35:53
【问题描述】:

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

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

| 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: no such table: other.Countries

【问题讨论】:

  • 我无法重现该错误。您是否尝试直接在 sqlite3 中单独执行查询(SELECT ID, Country ...)?
  • 你有什么错误吗?

标签: python sqlite


【解决方案1】:

这是一个成功获得您想要的结果的解决方法。


不必编写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)

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

【讨论】:

  • 很高兴知道!谢谢。
  • 是的,没问题 :-)
【解决方案2】:

当前错误可能是由拼写错误或其他小问题引起的。我可以创建此处描述的数据库并在修复小错误后成功插入:行尾缺少反斜杠并为所选列添加限定符。

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

cur.execute("\
        INSERT INTO Movies \
        (ID, Country) \
        SELECT m.ID, c.Country\
        FROM other.Movies  m CROSS JOIN other.Countries c \
        WHERE m.ID = c.ID AND c.Country = 'Peru'")

【讨论】:

    猜你喜欢
    • 2020-09-28
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    • 2017-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多