【问题标题】:How to create INSERT query that adds sequence number in one table to another如何创建将一个表中的序列号添加到另一个表的 INSERT 查询
【发布时间】:2019-04-23 06:05:32
【问题描述】:

我在 Postgres 10.7 数据库中有一个表 sample_1,其中包含一些纵向研究数据和每个 key 的递增 sequence 数字。我需要从暂存表 (sample_2) 中的 INSERT 数据相应地维护 sequence 列。

sequence 数字从 0 开始。我假设我需要一个查询来查找sample_1 中每个key 的最大sequence 数字,并将其添加到每个新行的后续序列号中。在这一步,我主要在序列号算术上苦苦挣扎。试过这个:

INSERT INTO sample_1 (KEY, SEQUENCE, DATA)
SELECT KEY, sample_2.SEQUENCE + max(sample_1.SEQUENCE), DATA
FROM sample_2;

但是,我收到错误消息,说我不能在第 2 行中使用“sample_1.SEQUENCE”,因为这是要插入的表。我不知道如何用我的插入序列进行算术运算!

样本数据:

sample_1

| KEY         | SEQUENCE | DATA |
+-------------+----------+------+
| YMH_0001_XX |     0    |  a   |
| YMH_0001_XX |     1    |  b   |
| YMH_0002_YY |     0    |  c   |
sample_2

| KEY         | SEQUENCE | DATA |
+-------------+----------+------+
| YMH_0001_XX |     1    |  d   |
| YMH_0002_YY |     1    |  e   |
| YMH_0002_YY |     2    |  f   |

对于插入的行,我想继续对每个 keysequence 数字进行升序。

为了清楚起见,此示例中的结果表将是 3 列和 6 行:

sample_1

| KEY         | SEQUENCE | DATA |
+-------------+----------+------+
| YMH_0001_XX |     0    |  a   |
| YMH_0001_XX |     1    |  b   |
| YMH_0001_XX |     2    |  d   |
| YMH_0002_YY |     0    |  c   |
| YMH_0002_YY |     1    |  e   |
| YMH_0002_YY |     2    |  f   |

【问题讨论】:

  • 如果您将sample_1 中的max(seq) 添加到所有行,那么结果表中最后两行的sequence 不应该是2 和3 吗?
  • @Crazy2crack - 我不确定我明白为什么? YMH_0002 的“1”中唯一的行是 sequence == 0 所以 max(1.sequence) + 2.sequence 分别等于 1 和 2?基线是每个人的代码序列为0,所有后续时间点为1、2等。
  • 理想情况下,您提供您的 Postgres 版本和准确的表定义(CREATE TABLE 声明阐明数据类型、约束、默认值,...)并且还披露任何可能的触发器、序列等参与。
  • @ErwinBrandstetter - 谢谢。我将编辑我的帖子。由于这是我的第一篇文章,它为我提供了生成它的导览,并特别提到除非特别需要,否则避免使用版本号。
  • 我冒昧地澄清了描述。如果我有任何错误,请编辑。

标签: sql postgresql sequence greatest-n-per-group


【解决方案1】:

那应该做你所追求的:

INSERT INTO sample_1 (key, sequence, data)
SELECT s2.key
     , COALESCE(s1.seq_base, -1)
     + row_number() OVER (PARTITION BY s2.key ORDER BY s2.sequence)
     , s2.data
FROM   sample_2 s2
LEFT   JOIN (
   SELECT key, max(sequence) AS seq_base
   FROM   sample_1
   GROUP  BY 1
   ) s1 USING (key);
笔记
  • 您需要在 sample_1 中的每个 key 的现有最大值 sequence 上进行构建。 (我将其命名为seq_base。)在子查询中计算并加入它。

  • row_number() 添加到其中,如图所示。这保留了输入行的顺序,丢弃了绝对数字。

  • 我们需要 LEFTJOIN 来避免使用来自 sample_2 的新键丢失行。
    同样,我们需要COALESCE 来为新键启动一个新序列。默认为 -1 以在添加基于 1 的行号后有效地以 0 开始序列。

  • 这对于并发执行是不安全的,但我认为这不是您的用例。

【讨论】:

  • 非常感谢,欧文!我想我可以看到它是如何工作的 - 我会看看,看看我会怎么做。
猜你喜欢
  • 2020-01-23
  • 2011-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-22
  • 1970-01-01
相关资源
最近更新 更多