Слияние двух столбцов из двух таблиц в PL / SQL - PullRequest
2 голосов
/ 08 апреля 2011

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

Назначение

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

Код Пока

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 ]

3 голосов
/ 08 апреля 2011

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

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'));
1 голос
/ 08 апреля 2011

Странно, 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);

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

EDIT:

Я думаю, что ваша настоящая проблема может быть связана с использованием 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));
0 голосов
/ 09 апреля 2011

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

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

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

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

0 голосов
/ 08 апреля 2011

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

...