Объединить столбцы и добавить цифры postgresql

Учитывая таблицу table1 в PostgreSQL:

number1 | number2 | min_length | max_length
40      |  1801   |     8      |     8  
40      |  182    |     8      |     8  
42      |  32     |     6      |     8  
42      |  4      |     6      |     6  
43      |  691    |     9      |     9  

Я хочу создать новую таблицу table2, например:

start        |      stop
4018010000   |      4018019999  
4018200000   |      4018299999  
42320000     |      42329999
423200000    |      423299999
4232000000   |      4232999999
42400000     |      42499999  
43691000000  |      43691999999  

Итак, новая таблица будет состоять из:

column_1 = a concatenation of old_column_1 + old_column_2 + a number of "0" equal to (old_column_3 - length of the old_column_2)
column_2 = a concatenation of old_column_1 + old_column_2 + a number of "9" equal to (old_column_3 - length of the old_column_2) 

А когда min_length не равно max_length, мне нужно учесть все возможные длины. Итак, для строки "42";"32";6;8 все длины равны: 6,7 и 8.

Я попытался создать новую таблицу table2 AS table1, затем создать новые столбцы start и stop, а затем объединить столбцы 1 и 2 следующим образом:

create table table2 as select * from table1;
alter table table2 add column start text,
                   add column stop text;
update table2 set start = number1 || number2

Для конкатенации первых 2 столбцов. Но я не могу понять, как сделать всю конкатенацию, чтобы добавить «0» и «9».


person Savas31    schedule 19.05.2020    source источник


Ответы (1)


Предполагая, что все столбцы равны NOT NULL, а max_length всегда больше, чем min_length, это работает:

CREATE TABLE table2 AS
SELECT t.number1::text || rpad(t.number2::text, len, '0') AS start
     , t.number1::text || rpad(t.number2::text, len, '9') AS stop
FROM   table1 t, generate_series(min_length, max_length) len

db‹>скрипка здесь

Руководство для generate_series() и rpad().

Если number1 или number2 может быть NULL, добавьте COALESCE:

SELECT COALESCE(t.number1::text, '') || rpad(COALESCE(t.number2::text,''), len, '0') AS start
     , COALESCE(t.number1::text, '') || rpad(COALESCE(t.number2::text,''), len, '9') AS stop
FROM table1 t, generate_series(min_length, max_length) len;

db‹>скрипка здесь

Если min_length или max_length может быть NULL, вам придется определить, что должно произойти.

person Erwin Brandstetter    schedule 19.05.2020
comment
Спасибо. Но у меня есть некоторые поля, которые пусты. Например, если у меня в столбце номер 2 есть пустое поле, этот случай не будет обрабатываться в таблице 2, и я потеряю данные для этого конкретного поля. Есть ли решение для этого случая? - person Savas31; 20.05.2020
comment
@ Savas31: Вот почему вы должны указать в вопросе определение таблицы. Исправить с помощью COALESCE. - person Erwin Brandstetter; 20.05.2020
comment
Спасибо, я попробовал CREATE TABLE table3 AS SELECT t.number1 :: text || rpad(COALESCE(t.number2::text,''), len, '0') AS start, t.number1::text || rpad(COALESCE(t.number2::text,''), len, '9') AS stop FROM table1 t , generate_series(min_length, max_length) len; но результат тот же. - person Savas31; 20.05.2020