【问题标题】:How to create multiple copies of a data row while applying data from another table in SQL如何在 SQL 中应用另一个表中的数据时创建数据行的多个副本
【发布时间】:2013-07-27 13:35:26
【问题描述】:

环境:INFORMIX 9.50C1、AIX 6.1

与我尝试做的最接近的类比是邮件合并。这是场景:

一个表 (CLIENTS) 有大量列(72 列)。该表包含客户数据,列代表客户的各种属性。

CLIENT_ID     RPQ_ID    Attrib2     Attrib3 ... Attrib71

表上的唯一键是客户端 ID:CLIENT_ID,它是一个 12 个字符的字母数字字段。所有其他列都允许重复。

CLIENTS 表中的一行被设置为一组新客户的模板。

CLIENT_ID     RPQ_ID    Attrib2     Attrib3 ... Attrib71
TEMPLATE_017  000000    London017   CLS12   ... 12

我有第二个表 (TMP_IMPORT),其中包含一个新客户端 ID 列表以及一个附加的非唯一属性 (RPQ ID)。导入列表有大约 2000 行。

CLIENT_ID     RPQ_ID
GPR3344       HG777
JND4111       JL888
JPS3172       JL888
PAP2171       JL888
...

任务是执行邮件合并的等效操作:使用 TMP_IMPORT 中的 client_id 和 rpq_id 值以及模板行中的所有其他列将 2000 个新行添加到 CLIENTS 表中。

表 CLIENTS 中的预期结果是

CLIENT_ID     RPQ_ID   Attrib2     Attrib3 ... Attrib71
TEMPLATE_017  000000   London017   CLS12   ... 12
GPR3344       HG777    London017   CLS12   ... 12
JND4111       JL888    London017   CLS12   ... 12
JPS3172       JL888    London017   CLS12   ... 12
PAP2171       JL888    London017   CLS12   ... 12
...

这一切都发生在一家大公司内,就访问控制、执行权限等而言,灵活性非常低。解决方案必须使用直接 SQL,没有 shell 脚本、过程和第三方库。

另外,请不要枚举列。我见过的常见解决方案之一是加入表格并指定每个数据列的来源,如

select TMP_IMPORT.CLIENT_ID, 
         TMP_IMPORT.RPQ_ID, 
         CLIENTS.Attrib2, 
         CLIENTS.Attrib3, 
         ..., 
         CLIENTS.Attrib71
from TMP_IMPORT, CLIENTS ...

这对于只有几列的表来说是合理的,但我希望有人有更优雅的解决方案。

谢谢!

【问题讨论】:

  • 请注意,没有正式发布的 9.50 版本;它在发布前被重新标记为 10.00。系统中存在(并且仍然存在)9.5x 版本的痕迹。还要注意,Informix 10.00 早已停止服务;您应该升级到 12.10(或在紧要关头升级到 11.70)。

标签: sql email merge duplicates informix


【解决方案1】:

你似乎知道你想要的查询:

insert into clients(client_id, rpt_id, . . . , Attrib71)
    select ti.CLIENT_ID, ti.RPQ_ID, c.Attrib2, c.Attrib3, ..., CLIENTS.Attrib71
    from TMP_IMPORT ti cross join
         (select c.*
          from CLIENTS c
          where client_id = 'Template_017'
         ) c;

您的问题似乎是获取列名列表。获取列的最简单方法如下:

select colname
from syscolumns c join
     systables t
     on c.tabid = t.tabid and t.tabname = 'CLIENTS'
order by colno;

其实你可以这样做:

select colname || ', '

然后将结果复制到insert 列列表的查询编辑器中(并删除最后的逗号)。然后将它们也复制到select 列表中的适当位置。

【讨论】:

  • 我喜欢使用系统表来获取列名的想法。但是这个解决方案仍然需要“外部”跳转到编辑器。有没有办法动态创建查询,而不是在编辑器中构造它。
  • @user2624414 。 . .在大多数数据库中,答案是“是”。 Informix 没有 group_concat()listagg() 等价物,因此在 Informix 中要困难得多。
  • Informix 以小写形式存储表名,除非您对它非常坚定(并且您不想对它那么坚定)。请参阅Show a one to many relationship as 2 columns - 1 unique row (ID & comma separated list) 了解如何为 Informix 创建 GROUP_CONCAT。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-10
  • 1970-01-01
  • 1970-01-01
  • 2013-03-03
  • 1970-01-01
  • 2016-04-13
  • 1970-01-01
相关资源
最近更新 更多