我想从Postgres数据库的表中洗牌一些列。我有两百万排。我需要通过另一个更新所有非空值。
我需要保留相同的数据集。不可能有两次相同的值。不可能用NEXT值交换数据,因为如果我对另一列执行相同的过程,我将保留相同的链接。这是为了匿名我的数据库。只需对数据进行混洗并保留数据集。
示例(更改名字和姓氏):
Id|Firstname|姓
-|-|
1|Albert|Einsten
2|艾萨克|牛顿
3||居里夫人
4|Alexandre|格雷厄姆·贝尔
5|托马斯|爱迪生
无序排列名字列:
Id|Firstname|姓
-|-|
1|艾萨克|格雷厄姆·贝尔
2|阿尔伯特|爱迪生
3||Einsten
4|托马斯|牛顿
5|Alexandre|居里夫人
如何以快速的过程做到这一点?
2条答案
按热度按时间6qfn3psc1#
这将以完全随机的方式调整列
firstname
中的值:“完全随机”包括某些列可能保留其原始值。(排得越多,机会就越小。)这实际上是数据匿名化的最佳选择。那么这些值就是真正的随机的。如果我们强制切换,读取器将获得与给定ID关联的不同值的最低信息。
它还遵守了您令人惊讶的规则,即只对非空值进行混洗。
对需要洗牌的每一列重复上述步骤。
在不排除
NULL
值的情况下,对于任意数量的列,此单个查询的运行成本更低:如果
id
是一个无间隙序列,我们可以把t1
从方程中去掉,然后把t0.id
和t2.rn
结合起来。(排除空值时不起作用。)fiddle
tf7tbtn22#
考虑到更新后的需求,使用Erwin Brandstetter的解决方案这样的策略可能会更好,该解决方案可以轻松地应用于任意数量的列,但是我将把我最初的答案留给第二篇专栏的更新。
原答案(要求洗一栏):
鉴于您对洗牌顺序的要求非常笼统,我不确定这实际上会有多大帮助,但我认为它回答了您的问题:
这里的想法是,内部查询将值移位1(忽略空值)。使用
COALESCE
是因为第一个没有进行中的条目,所以它依赖于某个LAST_VALUE
逻辑来获得最后一个值(即,它的行为就像移位循环一样)。周围的
UPDATE
语句将测试连接到子查询,以实际更新数据。你可以看到它在工作。
已更新(要求同时洗牌第二列):
考虑到还需要对第二个字段进行改组的更新要求,您可以在其中应用不同的逻辑:
这只是在相反方向上移动
lastname
,因此从前一个非空行获取firstname
(环绕),从下一个非空行获取lastname
(环绕)。这两列都将更改。这是一个fiddle of it working