Объединение двух столбцов из двух таблиц в PL/SQL

У меня огромные трудности при попытке объединить два столбца из двух таблиц в PL/SQL. Я работаю над этим с 9:00, и я сдаюсь, пожалуйста, помогите мне.

Цель

Я хотел бы создать новую таблицу (назовите ее временная). Это объединяет информацию из двух других столбцов в двух разных таблицах.

Код пока

CREATE TABLE temp
    (
        temptimeKey           CHAR(24) NOT NULL ,
        temptimeHour          INTEGER NULL ,
        temptimeMinute        INTEGER NULL ,
        temptimeSecond        INTEGER NULL ,
        temptimeMonth         INTEGER NULL ,
        temptimeDay           INTEGER NULL ,
        temptimeYear          INTEGER NULL ,
        temptimeQuarter       INTEGER NULL ,
        CONSTRAINT  XPKTEMPTIME PRIMARY KEY (temptimeKey)
    );

    insert into temp
    SELECT 
        TO_CHAR(busFareDate, 'MM/DD/YYYY HH:MM:SS Q'),
        TO_NUMBER(TO_CHAR(busFareDate, 'HH12')),
        TO_NUMBER(TO_CHAR(busFareDate, 'MI')),
        TO_NUMBER(TO_CHAR(busFareDate, 'SS')), 
        TO_NUMBER(TO_CHAR(busFareDate, 'MM')),
        TO_NUMBER(TO_CHAR(busFareDate, 'DD')),
        TO_NUMBER(TO_CHAR(busFareDate, 'YYYY')),
        TO_NUMBER(TO_CHAR(busFareDate, 'Q'))
    FROM 
        bus_fare
    UNION
    SELECT
        TO_CHAR(trainFareDate, 'MM/DD/YYYY HH:MM:SS Q'),
        TO_NUMBER(TO_CHAR(trainFareDate, 'HH12')),
        TO_NUMBER(TO_CHAR(trainFareDate, 'MI')),
        TO_NUMBER(TO_CHAR(trainFareDate, 'SS')), 
        TO_NUMBER(TO_CHAR(trainFareDate, 'MM')),
        TO_NUMBER(TO_CHAR(trainFareDate, 'DD')),
        TO_NUMBER(TO_CHAR(trainFareDate, 'YYYY')),
        TO_NUMBER(TO_CHAR(trainFareDate, 'Q'))
    FROM 
        train_fare;

    drop table temp cascade constraints;

Пока что этот код только дает мне нарушение уникального ограничения:

ERROR at line 1:
ORA-00001: unique constraint (OPS$FNAVA.XPKTEMPTIME) violated

Можете ли вы определить, что я делаю не так? (любая помощь приветствуется)

4 ответа

Решение

Попробуй это:

insert into temp
SELECT 
    TO_CHAR(busFareDate, 'MM/DD/YYYY HH:MI:SS Q'),
    TO_NUMBER(TO_CHAR(busFareDate, 'HH12')),
    TO_NUMBER(TO_CHAR(busFareDate, 'MI')),
    TO_NUMBER(TO_CHAR(busFareDate, 'SS')), 
    TO_NUMBER(TO_CHAR(busFareDate, 'MM')),
    TO_NUMBER(TO_CHAR(busFareDate, 'DD')),
    TO_NUMBER(TO_CHAR(busFareDate, 'YYYY')),
    TO_NUMBER(TO_CHAR(busFareDate, 'Q'))
FROM (
        SELECT busFareDate 
        FROM bus_fare 
        GROUP BY busFareDate
        UNION
        SELECT trainFareDate 
        FROM train_fare 
        GROUP BY trainFareDate) AS Dates
GROUP BY TO_CHAR(busFareDate, 'MM/DD/YYYY HH:MI:SS Q'),
        TO_NUMBER(TO_CHAR(busFareDate, 'HH12')),
        TO_NUMBER(TO_CHAR(busFareDate, 'MI')),
        TO_NUMBER(TO_CHAR(busFareDate, 'SS')), 
        TO_NUMBER(TO_CHAR(busFareDate, 'MM')),
        TO_NUMBER(TO_CHAR(busFareDate, 'DD')),
        TO_NUMBER(TO_CHAR(busFareDate, 'YYYY')),
        TO_NUMBER(TO_CHAR(busFareDate, 'Q'));

Странно, UNION должен удалять дубликаты автоматически. Это на СУБД Oracle?

Нарушения UNIQUE CONSTRAINT нарушены из-за того, что ваш запрос возвращает несколько строк для ключевого столбца таблицы, в которую вы вставляете.

В вашем случае TO_CHAR(trainFareDate, "MM/DD/YYYY HH:MM:SS Q") будет вставлен в ключевой столбец. Если есть две строки с одинаковыми ММ / ДД / ГГГГ ЧЧ: ММ: СС Q, вы получите эту ошибку, предполагая, что ваша СУБД действительно выполняет "UNION ALL".

Вы можете добавить второй столбец к первичному ключу, возможно, назовите его "SOURCE" и заполните его "BUS" или "TRAIN".

Или вы можете сделать полное внешнее объединение таблиц.

SELECT coalesce(busFareDate, trainFareDate) from
bus_fare FULL OUTER JOIN train_fare ON 
   (bus_fare.busFareDate = train_fare.trainFareDate);

Затем выполните всю работу, которую вам нужно сделать в день, используя ее как подзапрос.

РЕДАКТИРОВАТЬ:

Я думаю, что ваша настоящая проблема может быть связана с использованием HH / HH12.

Что делать, если вы делаете это:

SELECT 
    TO_CHAR(fareDate , 'MM/DD/YYYY HH24:MI:SS Q'),
    TO_NUMBER(TO_CHAR(fareDate , 'HH24')),
    TO_NUMBER(TO_CHAR(fareDate , 'MI')),
    TO_NUMBER(TO_CHAR(fareDate , 'SS')), 
    TO_NUMBER(TO_CHAR(fareDate , 'MM')),
    TO_NUMBER(TO_CHAR(fareDate , 'DD')),
    TO_NUMBER(TO_CHAR(fareDate , 'YYYY')),
    TO_NUMBER(TO_CHAR(fareDate , 'Q'))
 FROM 
    (SELECT coalesce(busFareDate, trainFareDate) fareDate from
     bus_fare FULL OUTER JOIN train_fare ON 
     (bus_fare.busFareDate = train_fare.trainFareDate));

Вы должны иметь тариф на автобус и время с той же датой / временем, нарушая ограничение. Почему бы не попытаться добавить столбец GUID в качестве первичного ключа временной таблицы и использовать newid() для генерации значения на каждой стороне объединения.

Попробуйте добавить TRIM() к вашему TO_CHAR(), как в:

TRIM(TO_CHAR(busFareDate, 'MM/DD/YYYY HH:MI:SS Q'))

Я думаю, что я помню, что TO_CHAR иногда добавляет пробел там, где вы этого не ожидаете. Если из-за пробела общая длина превысит 24 символа, он будет усечен при переходе в целевой столбец во временной таблице, что может создать впечатление, что дубликатов не существует (т. Е. Они различны). только последние 2 или 3 символа, которые обрезаются).

В качестве альтернативы, расширьте столбец CHAR(24) до чего-то большего, например CHAR(1000), просто чтобы посмотреть, исчезнет ли проблема.

Другие вопросы по тегам