sqlite:更新联接中的列

时间:2019-01-09 20:09:30

标签: pandas sqlite join sql-update

我尝试了以下答案,但找不到合适的方法

  1. SQLite inner join - update using values from another table
  2. How do I make an UPDATE while joining tables on SQLite?
  3. Update table values from another table with the same user name

这是问题所在。我有一个带两个表的sqlite数据库。在下面的代码中,我使用pandas插入一些虚拟值

WBReport.date = '2019-01-09'

这将产生两个表

import sqlite3
import pandas

conn = sqlite3.connect('foo.db')
curs = conn.cursor()

df1 = pandas.DataFrame([{'A' : 1, 'B' : 'a', 'C' : None}, {'A' : 1, 'B' : 'b', 'C' : None}, {'A' : 2, 'B' : 'c', 'C' : None}])
df1.to_sql('table1', conn, index = False)

df2 = pandas.DataFrame([{'A' : 1, 'D' : 'x'}, {'A' : 2, 'D' : 'y'}])
df2.to_sql('table2', conn, index = False)

pandas.read_sql('select * from table1', conn)
   A  B     C
0  1  a  None
1  1  b  None
2  2  c  None

现在,我想联接列pandas.read_sql('select * from table2', conn) A D 0 1 x 1 2 y 上的这两个表,并用结果A更新列table1.C

这是我尝试过的

  

上面列表中的解决方案1 ​​

D

错误

  

上面列表中的解决方案2

sql = """
    replace into table1 (C)    
    select table2.D
    from table2
    inner join table1 on table1.A = table2.A
"""
curs.executescript(sql)
conn.commit()
pandas.read_sql('select * from table1', conn)
     A     B     C
0  1.0     a  None
1  1.0     b  None
2  2.0     c  None
3  NaN  None     x
4  NaN  None     x
5  NaN  None     y
  

上面列表中的解决方案3

sql = """
    replace into table1 (C)
    select sel.D from (
    select table2.D as D
    from table2
    inner join table1 on table1.A = table2.A
    ) sel
"""
curs.executescript(sql)
conn.commit()
pandas.read_sql('select * from table1', conn)
     A     B     C
0  1.0     a  None
1  1.0     b  None
2  2.0     c  None
3  NaN  None     x
4  NaN  None     x
5  NaN  None     y

这显然是错误的,因为最后一行已更新为sql = """ update table1 set C = ( select table2.D from table2 inner join table1 on table1.A = table2.A ) """ curs.executescript(sql) conn.commit() pandas.read_sql('select * from table1', conn) A B C 0 1 a x 1 1 b x 2 2 c x ,应该为x

这时我几乎没有选择了。任何帮助都非常感激

2 个答案:

答案 0 :(得分:1)

I cannot quite remember (or explain intelligently) why solution 3 doesn't work but I think it's something like table1 in the subquery is not the "same" table1 being updated. (I have struggled with this in the past, and have developed habits to avoid it, no longer remember the reason).

I do know if you change
inner join table1 on table1.A = table2.A to where table1.A = table2.A it will work.

This will also work:

update table1 
    set C = (
    select table2.D
    from table2
    inner join table1 t1 on t1.A = table2.A
    and t1.A = table1.A
    )

Both of these solutions will set C to null if there is no matching row in table2.

答案 1 :(得分:1)

我认为正确的方法是使用 sqlite version 3.33 引入的 UPDATE-FROM 语法(在提出此问题时不可用):

UPDATE table1 AS dst
    SET C=src.D
    FROM table2 AS src
    WHERE dst.A=src.A