如何创建将一个 table 中的序列号添加到另一个的 INSERT 查询
How to create INSERT query that adds sequence number in one table to another
我在 Postgres 10.7 数据库中有一个 table sample_1
,其中包含一些纵向研究数据和每个 key
。我需要 INSERT
来自暂存 table (sample_2
) 的数据,相应地维护 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',因为那是要插入的 table。我不知道如何用我的插入序列进行算术运算!
示例数据:
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 |
我想为插入的行继续升序 sequence
个数字 key
。
为了清楚起见,此示例中的结果 table 将是 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 |
这应该可以满足您的需求:
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()
。这保留了输入行的顺序,丢弃了绝对数字。
我们需要 LEFT
JOIN
来避免使用新键丢失行来自 sample_2
.
同样,我们需要 COALESCE
来开始新的密钥序列。默认为 -1 以在添加基于 1 的行号后有效地以 0 开始序列。
这对于并发执行是不安全的,但我不认为那是你的用例。
我在 Postgres 10.7 数据库中有一个 table sample_1
,其中包含一些纵向研究数据和每个 key
。我需要 INSERT
来自暂存 table (sample_2
) 的数据,相应地维护 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',因为那是要插入的 table。我不知道如何用我的插入序列进行算术运算!
示例数据:
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 |
我想为插入的行继续升序 sequence
个数字 key
。
为了清楚起见,此示例中的结果 table 将是 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 |
这应该可以满足您的需求:
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()
。这保留了输入行的顺序,丢弃了绝对数字。我们需要
LEFT
JOIN
来避免使用新键丢失行来自sample_2
.
同样,我们需要COALESCE
来开始新的密钥序列。默认为 -1 以在添加基于 1 的行号后有效地以 0 开始序列。这对于并发执行是不安全的,但我不认为那是你的用例。