PostgreSQL добавляет столбец id, который увеличивается на основе данных

89
13

Я относительно новичок в использовании Postgres, исходя из фона MySQL. Я использую Postgres 9.3.4 для Windows x64.


Мы предоставляем данные в нескольких текстовых файлах с фиксированной длиной. Первая цифра в каждой строке - это число от 1 до 4, которое указывает тип записи данных в этой строке. Строки группируются последовательно так, что сначала всегда будет строка типа 1, за которой следует ноль или более строк других типов.


data_x.txt
---------------------
1data01
2data02
4data03
4data04
1data05
1data06
3data07

Чтобы импортировать это в Postgres, я использовал следующие команды SQL:


CREATE TABLE data_raw (
raw_data TEXT
);

COPY data_raw FROM 'C:\path\data_x.txt' ...; -- Repeated for each file

ALTER TABLE data_raw
ADD COLUMN indicator integer;

UPDATE data_raw SET
indicator = CAST(substr(raw_data, 1, 1) AS integer),
raw_data = substr(raw_data, 2);


Затем создаю таблицы для каждого из 4 типов записей:


CREATE TABLE table_1 SELECT raw_data FROM data_raw WHERE indicator = 1;
CREATE TABLE table_2 SELECT raw_data FROM data_raw WHERE indicator = 2;
CREATE TABLE table_3 SELECT raw_data FROM data_raw WHERE indicator = 3;
CREATE TABLE table_4 SELECT raw_data FROM data_raw WHERE indicator = 4;

Что мне нужно сделать, но я не уверен, что это также добавить столбец "id" для каждой группы, где индикатор начинается с 1. Мы будем получать еженедельные обновления, поэтому мне нужно указать начальный идентификатор для каждой партии, Поэтому, если эта партия начинается с id = 225, я хочу получить следующие данные из данных примера:


table_1
id | raw_data
--------------------
225 | data01
226 | data05
227 | data06

table_2
id | raw_data
--------------------
225 | data02

table_3
id | raw_data
--------------------
227 | data07

table_4
id | raw_data
--------------------
225 | data03
225 | data04

спросил(а) 2021-01-25T18:42:06+03:00 4 месяца, 2 недели назад
1
Решение
62

Попробуйте что-то подобное для генерации идентификатора для каждой группы данных:


SELECT sum(case when indicator = 1 then 1 else 0 end ) over(order by /*something to define the order*/) as id_base
from data_raw

Он будет генерировать id_base для каждой группы данных. Если вам нужно начать с определенного идентификатора - просто добавьте этот идентификатор в id_base.

ответил(а) 2021-01-25T18:42:06+03:00 4 месяца, 2 недели назад
45

Спасибо за ввод.


Используя предложение Игоря, я придумал следующее решение:


CREATE TABLE data_raw (
raw_data TEXT
);

COPY data_raw FROM 'C:\path\data_x.txt' ...; -- Repeated for each file

ALTER TABLE data_raw
ADD COLUMN pk_id serial,
ADD COLUMN id integer,
ADD COLUMN indicator integer;

UPDATE data_raw SET
indicator = CAST(substr(raw_data, 1, 1) AS integer),
raw_data = substr(raw_data, 2);

CREATE TABLE id_base AS
SELECT
pk_id,
sum(CASE WHEN indicator = 1 THEN 1 ELSE 0 END) OVER (ORDER BY pk_id) AS rec_id
FROM data_raw;

CREATE INDEX id_base_pk ON id_base USING btree(pk_id);

UPDATE data_raw r SET
id = (SELECT rec_id FROM id_base b WHERE b.pk_id = r.pk_id);

DROP TABLE id_base;

ответил(а) 2021-01-25T18:42:06+03:00 4 месяца, 2 недели назад
45

1) добавить PK,


2) Создать таблицу словаря для типа...

CREATE TABLE "public"."data_raw"(
"id" Serial NOT NULL,
"id_type" Integer NOT NULL,
"raw_data" Text
);

CREATE TABLE "public"."data_raw_type"(
"id" Serial NOT NULL,
"name" Character varying(30));

ответил(а) 2021-01-25T18:42:06+03:00 4 месяца, 2 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема