高级SQLite更新表查询

高级SQLite更新表查询,sqlite,Sqlite,我正在尝试更新数据库的表B,如下所示: Table A: id, amount, date, b_id 1,200,6/31/2012,1 2,300,6/31/2012,1 3,400,6/29/2012,2 4,200,6/31/2012,1 5,200,6/31/2012,2 6,200,6/31/2012,1 7,200,6/31/2012,2 8,200,6/31/2012,2 Table B: id, b_amount, b_date 1,0,0 2,0,0 3,0,0 现在,通

我正在尝试更新数据库的表B,如下所示:

Table A:
id, amount, date, b_id
1,200,6/31/2012,1
2,300,6/31/2012,1
3,400,6/29/2012,2
4,200,6/31/2012,1
5,200,6/31/2012,2
6,200,6/31/2012,1
7,200,6/31/2012,2
8,200,6/31/2012,2

Table B:
id, b_amount, b_date
1,0,0
2,0,0
3,0,0
现在,通过此查询,我可以在一次选择中获得所需的所有数据:

SELECT A.*,B.* FROM A LEFT JOIN B ON B.id=A.b_id WHERE A.b_id>0 GROUP BY B.id

id, amount, date, b_id, id, b_amount, b_date
1,200,6/31/2012,1,1,0,0
3,400,6/29/2012,1,1,0,0
现在,我只想将所选列amount复制到b_amount,将date复制到b_date

b_amount=amount, b_date=date
导致

id, amount, date, b_id, id, b_amount, b_date
1,200,6/31/2012,1,1,200,6/31/2012
3,400,6/29/2012,1,1,400,6/29/2012
我试过合并,但没有成功。 有经验的人对此有解决方案吗

解决方案: 多亏了下面的答案,我终于想出了这个。这可能不是最有效的方法,但是只进行一次更新就可以了。这将为您插入每个组的第一个对应条目

REPLACE INTO A SELECT id, amount, date FROM 
(SELECT  A.id, A.amount, B.id as Bid FROM A INNER JOIN B ON (B.id=A.B_id)
ORDER BY A.id DESC) 
GROUP BY Bid;

警告:一些RDBMS将返回上面显示的2行。其他人将返回行的笛卡尔乘积,即A行乘以B行

一个棘手的方法是生成SQL,然后执行SQL

SELECT "update B set b.b_amount = ", a.amount, ", b.b_date = ", a.date, 
" where b.id = ", a.b_id
FROM A LEFT JOIN B ON B.id=A.b_id WHERE A.b_id>0 GROUP BY B.id
现在添加批处理终止符并执行此SQL。查询结果应该如下所示

 update B set b.b_amount = 200, b.b_date = 6/31/2012 where b.id = 1 

 update B set b.b_amount = 400, b.b_date = 6/29/2012 where b.id = 3 

注意:一些RDBMS将以不同的方式处理日期。有些需要引号。

因此,您要查找的似乎是更新查询内部的连接。在mySQL中,您将使用

UPDATE B INNER JOIN A ON B.id=A.b_id SET B.amount=A.amount, B.date=A.date;
但正如相关问题所指出的,sqlite不支持这一点。但是,使用“替换”有一个变通方法:

REPLACE INTO B 
SELECT B.id, A.amount, A.date FROM A 
LEFT JOIN B ON B.id=A.b_id 
WHERE A.b_id>0 GROUP BY B.id;
查询只需为所有应保持其状态的列填写表B的值,并为复制的值填写表A的值。确保SELECT语句中的列顺序符合表B的列顺序,并且所有列都已提到,否则将丢失这些字段的数据。这对于表B的未来更改可能是危险的。因此,请记住在更改表B时更改此查询的列顺序/存在性


有点离题,因为你没有要求:
a.b_id
显然是b.id的外键。看来你正在使用值<代码> 0代码/代码>外键来表示B中没有对应的条目(从你的SELECT和<代码>中推断,A.ByID> 0 ),你应该考虑使用<代码> null <代码>值。使用
内部连接时
可以完全删除WHERE子句,而不是
左连接。DBS随后将整理所有不满意的关系。

谢谢!我得到相应的列,但如何执行附加列?这似乎不是一种优雅的方式。谢谢,这很有效!不过,还有一件事:GROUPBY语句使用与查询对应的最后一行,但我需要第一行。