SQL-запрос для вставки нескольких столбцов в один, дублируя остальные поля в каждой строке - PullRequest
0 голосов
/ 20 сентября 2018

Добрый день!Я пытаюсь взять значения, которые охватывают несколько столбцов в одной таблице, и вставить их в один столбец в новой таблице, но для нескольких различных полей в несколько различных полей в новой таблице.

Например, в моем оригиналеВ таблице есть 5 столбцов для разных лекарств, я хочу вставить их в один столбец в новой таблице и просто дублировать значения других столбцов в строках для каждого лекарства, которое было вставлено.

Сообщение об ошибке, которое я получаюв том, что выражений больше, чем целей, что да, но некоторые вставки помечены одинаково.Разве «Вставка» не позволяет вставлять несколько элементов в один столбец?Есть ли другой метод или функция для этого?

Заранее спасибо!

Это моя недавно созданная таблица:

CREATE TABLE source.roster_new
(
person_number text COLLATE pg_catalog."default",
date_of_birth timestamp without time zone,
person_last_name text COLLATE pg_catalog."default",
person_first_name text COLLATE pg_catalog."default",
dx_code text COLLATE pg_catalog."default",
dx_description text COLLATE pg_catalog."default",
dx_first_date timestamp without time zone,
gender text COLLATE pg_catalog."default",
age numeric,
last_test_type text COLLATE pg_catalog."default",
last_test_date timestamp without time zone,
medication text COLLATE pg_catalog."default"
)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;

И это мой код длявставка в эту новую таблицу из старой:

INSERT INTO source.roster_new
SELECT
person_number
,date_of_birth
,person_last_name 
,person_first_name 
,asthma_code AS dx_code
,copd_code AS dx_code
,asthma_description AS dx_description
,copd_description AS dx_description
,first_asthma_date AS dx_first_date
,first_copd_date AS dx_first_date
,gender 
,age 
,case when(last_flu_date IS NOT NULL) THEN 'Flu' End AS last_test_type
,case when(last_spiro_date IS NOT NULL) THEN 'Spirometry' End AS last_test_type
,case when(last_pneumo_date IS NOT NULL) THEN 'Pneumococcal' End AS last_test_type
,last_flu_date AS last_test_date
,last_spiro_date AS last_test_date
,last_pneumo_date AS last_test_date
,medication1 AS medication
,medication2 AS medication
,medication3 AS medication
,medication4 AS medication
,medication5 AS medication
FROM source.roster

РЕДАКТИРОВАТЬ: я не мог понять, как форматировать таблицы, поэтому я загрузил два изображения результатов, которые я надеюсь увидеть и что оригиналданные будут выглядеть следующим образом.

Исходное изображение таблицы

Новое изображение таблицы

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Я предполагаю, что вы хотите

CREATE TABLE tab (patient text, med text);

INSERT INTO tab (patient, med, med, med)
VALUES ('Joe', 'vomitol', 'putrefac', 'abrasil');

Как вы выяснили, это не сработает.

Вы можете сохранить несколько значений в столбцеиспользуя массив, однако:

CREATE TABLE tab (patient integer, med text[]);

INSERT INTO tab (patient, med)
VALUES ('Joe', ARRAY['vomitol', 'putrefac', 'abrasil']);

Однако это нарушает первую нормальную форму для реляционных баз данных, и хотя нарушение нормальной формы не является смертным преступлением, это следует сделатьс осторожностью.

Мой совет - использовать массивы только в том случае, если вам не нужно интенсивно использовать элементы массива внутри базы данных, например, в состоянии WHERE, которое вы хотите проиндексировать.По сути, если это одно значение для базы данных, то лучше использовать массивы.

Если, однако, ваша цель - избежать избыточных данных в базе данных (вы не хотитехранить общие столбцы несколько раз), решение не для денормализации, а для нормализации больше :

CREATE TABLE tab_common (
   id integer PRIMARY KEY,
   patient text NOT NULL
);

CREATE TABLE tab_med (
   id integer PRIMARY KEY,
   common_id integer NOT NULL REFERENCES tab_common(id),
   med text NOT NULL
);

INSERT INTO tab_common (id, patient)
VALUES (1, 'Joe');

INSERT INTO tab_med (id, common_id, med)
VALUES (1, 1, 'vomitol'),
       (2, 1, 'putrefac'),
       (3, 1, 'abrasil');

Тогда ваша таблица соответствует третья нормальная форма , и с тобой все будет в порядке.

0 голосов
/ 20 сентября 2018

может использовать объединение для единственного выбора, который вам нужен

    INSERT INTO source.roster_new ( 
        person_number
        ,date_of_birth
        ,person_last_name 
        ,person_first_name 
        ,asthma_code AS dx_code
        ,dx_description
        ,dx_first_date
        ,gender 
        ,age 
        ,last_test_type
        , last_test_date
        ,medication )

    SELECT 
        person_number
        ,date_of_birth
        ,person_last_name 
        ,person_first_name 
        ,asthma_code AS dx_code
        ,asthma_description AS dx_description
        ,first_asthma_date AS dx_first_date
        ,gender 
        ,age 
        ,'Flu' End AS last_test_type
        ,last_flu_date AS last_test_date
        ,medication1 AS medication
    FROM source.roster
    where last_flu_date IS NOT NULL
    UNION 
    SELECT
        person_number
        ,date_of_birth
        ,person_last_name 
        ,person_first_name 
        ,asthma_code AS dx_code
        ,asthma_description AS 
        ,first_asthma_date AS 
        ,gender 
        ,age 
        ,'Spirometry' 
        ,last_spiro_date
        ,medication2
    FROM source.roster
    where last_spiro_date IS NOT NULL
    UNION 
    SELECT
        person_number
        ,date_of_birth
        ,person_last_name 
        ,person_first_name 
        ,asthma_code AS dx_code
        ,asthma_description AS 
        ,first_asthma_date AS 
        ,gender 
        ,age 
        ,'last_pneumo_date' 
        ,last_pneumo_date
        ,medication3
    FROM source.roster
    where last_pneumo_date

и так далее ...

...