如何纠正 PL/pgSQL 中缺少引用的“一对多表”?

Posted

技术标签:

【中文标题】如何纠正 PL/pgSQL 中缺少引用的“一对多表”?【英文标题】:How to correct ‘One to Many table’ with missing references in PL/pgSQL? 【发布时间】:2019-02-10 16:01:51 【问题描述】:

我有一个大型数据文件,在每个相关子集的第一条记录上都有一个唯一的 11 位引用,但在属于相同子集的后续记录上没有,而是具有虚假的 1 或 2 位引用。该表按照最初创建的顺序排列,因此子集仍然正确分组在一起,包含这些引用的字段称为“旧引用”。我刚刚创建了一个名为“New Ref”的新字段,我想用每个子集的所有适当的 11 位引用填充该字段。如何在我可以在 PL/pgSQL 上运行的脚本中最好地实现这一点?

以下是数据的示例(当前),我希望它更新:

   Current datafile
__________________________________
ID  | Old Ref       | New Ref
==================================
1   | 14740807000   |
2   | 1             |    
3   | 2             |    
4   | 3             |
5   | 58            |
6   | 14735113000   | 
7   | 1             |               
8   | 2             |    
9   | 39            |   
10  | 4             |    
11  | 5             |    
12  | 14915146000   | 
13  | 9             |        
14  | 27            | 
15  | 14915146000   | 
16  | 3             | 
17  | 4             |    
==================================

Sought updated datafile
__________________________________
ID  | Old Ref       | New Ref
==================================
1   | 14740807000   | 14740807000
2   | 1             | 14740807000    
3   | 2             | 14740807000    
4   | 3             | 14740807000 
5   | 58            | 14740807000
6   | 14735113000   | 14735113000 
7   | 1             | 14735113000               
8   | 2             | 14735113000    
9   | 39            | 14735113000    
10  | 4             | 14735113000    
11  | 5             | 14735113000    
12  | 14915146000   | 14915146000
13  | 9             | 14915146000        
14  | 27            | 14915146000
15  | 14915175959   | 14915175959
16  | 3             | 14915175959
17  | 4             | 14915175959    
==================================

我有我认为在 MS Access 中执行此操作的一种巧妙方法,但它无法处理我需要更新的数据文件的大小,这也是我切换到 PostgreSQL 的原因之一。

这是 MS Access 脚本:

Sub UpdateRef()
On Error GoTo ErrorHandler

Dim strSQL, Var1 As String
Dim rs As New ADODB.Recordset

rs.Open "SELECT test.* FROM test", CurrentProject.Connection, adOpenDynamic, adLockOptimistic

rs.MoveFirst
Var1 = rs![Old ref]
rs![New Ref] = Var1
rs.Update

Do Until rs.EOF
  'SysCmd acSysCmdUpdateMeter, n
  If len(rs![Old ref]) > 2 Then
    Var1 = rs![field2]
  End If
rs![New Ref] = Var1
rs.Update
rs.MoveNext
Loop
  rs.Close
ExitSub:
  Set rs = Nothing
  Exit Sub
ErrorHandler:
  Resume ExitSub
End Sub

【问题讨论】:

感谢您的建议 - 我现在已将其包含在内。 Old Ref的数据类型是什么? (因及时响应澄清请求而受到支持 - 干得好!) 【参考方案1】:

您可以使用update 声明来做到这一点:

update test t
set newref = (select tt.oldref from test tt where tt.id = (
  select max(id) from test where id <= t.id and length(oldref) = 11
));

见demo 这个:

select max(id) from test where id <= t.id and length(oldref) = 11

获取包含第 11 位 oldref 的行的 id

【讨论】:

以上是关于如何纠正 PL/pgSQL 中缺少引用的“一对多表”?的主要内容,如果未能解决你的问题,请参考以下文章

在 PL/PGSQL 动态 SQL 内部函数中引用局部变量

从 PL/PGSQL 引用会话变量 (\set var='value')

它可以引用 PL/pgSQL 变量或表列

如何在 PL/pgSQL 中创建嵌套函数?

PL/PGSQL - 无法将 SELECT 语句中的 array_agg 分配给变量

如何在 PL/pgSQL 中获取动态生成的字段名称的值