Как создать запрос INSERT, который добавляет порядковый номер из одной таблицы в другую - PullRequest
3 голосов
/ 23 апреля 2019

У меня есть таблица sample_1 в базе данных Postgres 10.7 с некоторыми данными продольных исследований и восходящим числом sequence на key.Мне нужно INSERT данные из промежуточной таблицы (sample_2), поддерживающие соответственно столбец sequence.

sequence числа основаны на 0.Я предполагаю, что мне нужен запрос для поиска наибольшего числа sequence на key в sample_1 и добавления его к порядковому номеру каждой новой строки.Я в основном борюсь на этом этапе с арифметикой порядкового номера.Попробовал это:

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

Тем не менее, я получаю ошибки, утверждающие, что я не могу использовать 'sample_1.SEQUENCE' в строке 2, потому что это таблица, в которую вставляется таблица.Я не могу понять, как сделать арифметику с моей последовательностью вставки!

Пример данных:

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для вставленных строк.

Для ясности, результирующая таблица в этом примере будет состоять из 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   |

1 Ответ

1 голос
/ 23 апреля 2019

Это должно делать то, что вы после:

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);
Примечания
  • Вам необходимо использовать существующий максимум sequence на key в sample_1.(Я назвал его seq_base.) Вычислите это в подзапросе и присоединитесь к нему.

  • Добавьте row_number() к нему, как показано.Это сохраняет порядок входных строк, исключая абсолютные числа.

  • Нам нужны LEFTJOIN, чтобы избежать потери строк сновые ключи от sample_2.
    Аналогично, нам нужно COALESCE, чтобы начать новую последовательность для новых ключей.По умолчанию -1 для эффективного запуска последовательностей с 0 после добавления номера строки на основе 1.

  • Это небезопасно для одновременного выполнения, но я не думаю, что это ваш вариант использования.

...