Redshift:使用来自另一个表的随机数据更新或插入列中的每一行

Posted

技术标签:

【中文标题】Redshift:使用来自另一个表的随机数据更新或插入列中的每一行【英文标题】:Redshift: Update or Insert each row in column with random data from another table 【发布时间】:2017-08-06 18:02:32 【问题描述】:
update testdata.dataset1
   set abcd = (select abc 
               from dataset2
               order by random()
               limit 1
              ) 

这样做只会使dataset2 表中的一个随机条目填充到dataset1 表的所有行中。

我需要生成从dataset2 表到dataset1 表的随机条目的每一行。

注意:dataset1 可以大于 dataset2

【问题讨论】:

Populate random data from another table的可能重复 抱歉,我必须为 redshift 和 postgree 创建一个。所以我有两个。 为什么需要创建两个问题?你可以用两个标签问一个问题。但是,您应该始终在问题中指出您使用的是哪个数据库,因为答案可能不同(尤其是对于 Redshift)。 是的,我会纠正的。很抱歉提出两个问题。可以编辑第一篇文章.. 【参考方案1】:

查询 1

您应该将abcd 传递到您的子查询中以防止“优化”。

UPDATE dataset1
    SET abcd = (SELECT abc
                FROM dataset2
                WHERE abcd = abcd
                ORDER BY random()
                LIMIT 1
               );

SQL Fiddle

查询 2

下面的查询在普通 PostgreSQL 上应该更快。

UPDATE dataset1
    SET abcd = (SELECT abc
                FROM dataset2
                WHERE abcd = abcd
                OFFSET floor(random()*(SELECT COUNT(*) FROM dataset2))
                LIMIT 1
               );

SQL Fiddle

但是,正如您所报告的,Redshift 并非如此,它是一种列式存储。

查询 3

在单个查询中从dataset2 获取所有记录比逐个获取记录更有效。让我们测试一下:

UPDATE dataset1 original
SET abcd = fake.abc FROM 
              (SELECT ROW_NUMBER() OVER(ORDER BY random()) AS id, abc FROM dataset2) AS fake
               WHERE original.id % (SELECT COUNT(*) FROM dataset2) = fake.id - 1;

SQL Fiddle

注意整数id列应该存在于dataset1中。 此外,对于大于dataset2 中记录数的dataset1.idabcd 是可预测的。

查询 4

让我们在dataset1 中创建整数fake_id 列,用随机值预填充它并对dataset1.fake_id = dataset2.id 执行连接:

UPDATE dataset1
SET fake_id = floor(random()*(SELECT COUNT(*) FROM dataset2)) + 1;  

UPDATE dataset1
SET abcd = abc
FROM dataset2
WHERE dataset1.fake_id = dataset2.id;

SQL Fiddle

查询 5

如果您不想将fake_id 列添加到dataset1,让我们计算fake_id 的“即时”:

UPDATE dataset1
SET abcd = abc
FROM (
SELECT with_fake_id.id, dataset2.abc FROM 
(SELECT dataset1.id,  floor(RANDOM()*(SELECT COUNT(*) FROM dataset2) + 1) AS fake_id FROM dataset1) AS with_fake_id
JOIN dataset2 ON with_fake_id.fake_id = dataset2.id ) AS joined
WHERE dataset1.id = joined.id;

SQL Fiddle


性能

在普通 PostgreSQL 上,查询 4 ​​似乎是最有效的。 我将尝试在试用 DC1.Large 实例上比较性能。

【讨论】:

那是红移吗? 这似乎有效,但更新 3 百万行的速度很慢......优化查询的任何方式或任何其他替代方式以使其更快一点? UPDATE testdata.ipdummy2 not successful执行SQL命令时出错:update testdata.ipdummy2 set ipreal = (select ip from testdata.ipdummy3 where ipreal is not null or ipreal is null... [亚马逊](500310)无效操作:捕获信号详细信息:------------------------------------ --------- 错误:捕获的信号代码:518 上下文:未知位置:未知:-1 进程:padbmaster [pid=21559] ----------------- ------------------; 1条语句失败。执行时间:4.88s 我猜上面的评论错误在偏移量中..我不确定 好吧,尝试在第二个查询中将WHERE abcd IS NOT NULL OR abcd IS NULL 替换为WHERE abcd = abcd。有效吗?

以上是关于Redshift:使用来自另一个表的随机数据更新或插入列中的每一行的主要内容,如果未能解决你的问题,请参考以下文章

如何使用条件使用来自单独表的数据更新一个表

来自另一个表的更新表上的SQL错误

用另一个表中的随机条目更新表的列

如何使用单独数据库中另一个表的数据更新一个表? [复制]

Redshift - 将文本列插入数据库表的问题

在 Redshift 中更新整个表的正确方法,删除表 + 创建表与截断 + 插入表