Объединение двух столбцов из двух таблиц в 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), просто чтобы посмотреть, исчезнет ли проблема.