2

首先,我使用 MonetDB Database Server Toolkit v1.1 (Feb2013-SP1) 中的 MonetDB 分支

我有两张表,想在不创建临时表的情况下完成以下两个功能:

1)从另一张表更新一张表;2) 从另一个表的聚合中更新一个表。

我想出了如何在 MySQL 和 Postgresql 中执行它们,但在 MonetDB 中类似的查询失败了。 

对于 1),假设我有以下两个表:

drop table t1; create table t1(id int, data int);
drop table t2; create table t2(id int, data int);
delete from t1; insert into t1 values (0, 0), (1,1), (2,2); select*from t1;
delete from t2; insert into t2 values (1,2), (2, 3), (3,4); select*from t2;

当它们的 id 匹配时,我们需要将 t1.data 设置为 t1.data+t2.data,t1.id=t2.id。

在 MySQL 中,我们可以使用:

update t1 inner join t2 on t1.id=t2.id set t1.data=t1.data+t2.data;

在 Postgresql 中,我们可以使用:

with tmp as (select t1.id, t1.data+t2.data as data from t1,t2 where t1.id=t2.id) update t1 set data = tmp.data from tmp where t1.id=tmp.id;select*from t1;

或者对于两者,我们可以使用:

update t1 set data=(select t1.data+t2.data from t2 where t2.id=t1.id) where exists (select * from t2 where t1.id=t2.id);

但是它们都不能在 MonetDB 中工作。

这个问题类似于之前提出的问题(https://www.monetdb.org/pipermail/users-list/2011-August/005072.html),但回答的建议似乎不正确。那里的两个表对于元组 id=2 具有相同的值。

update t1 set data=(select data+t2.data from t2 where t2.id=t1.id) where exists (select * from t2 where t1.id=t2.id);

因此,在这个查询中,select 的第一个子查询中的数据字段实际上来自 t2 而不是 t1。但是,如果我们更改为 t1.data,解析器将无法识别名称 t1。它以某种方式连接它可以识别条件子句中的 t1.id。

并不是说以下查询也不正确:

update t1 set data=(select t1.data + t2.data from t1, t2 where t2.id = t1.id) where exists (select t2.id from t2 where t2.id = t1.id);

由于子查询变得独立于外部查询,并且可能导致违反赋值基数的多个值。

更改 t1 和 t2 中的字段名称也无济于事。

对于 2),假设我们有以下两个表:

delete from t1; insert into t1 values (0, 0), (1,1), (2,2); select * from t1;
delete from t2; insert into t2 values (1,2), (2, 3), (3,4), (2,5); select * from t2;

我们想要聚合 t2 中的值并将结果分配给 t1。

在 MySQL 中,我们可以使用:

update t1 inner join t2 on t1.id=t2.id set t1.data=(select sum(t2.data) from t2 where t2.id=t1.id group by t2.id);

或者在 Postgresql 中,我们可以使用:

with tmp as (select t2.id, sum(t2.data) as data from t2 group by t2.id) update t1 set data=tmp.data from tmp where t1.id=tmp.id;

在 MonetDB 中,如何在更新语句中正确编写这样的子查询?

看起来 MonetDB 在 select 中支持 with 子句,但在 update 中不支持。

with tmp as (select t2.id, sum(t2.data) as data from t2 group by t2.id) select * from tmp; 

我也很想知道使用子查询和创建临时表之间的性能差异。

谢谢!

4

1 回答 1

1

根据 MonetDB 邮件列表 Niels 的回复,随着 2014 年 1 月的发布,这两个功能可以表示为以下两种工作形式:

对于 1):

update t1 set data=(select t1.data+t2.data from t2 where t2.id=t1.id) where exists (select * from t2 where t1.id=t2.id);

对于 2):

update t1 set data = (select sum(t2.data) from t2 where t2.id=t1.id group by t2.id) where exists (select * from t2 where t1.id=t2.id);
于 2014-03-04T01:07:03.817 回答