在PL/SQL中合并两个表中的两个列



我在PL/SQL中合并两个表中的两列时遇到了巨大的困难。我从早上9点就开始做这个了,现在我放弃了,请帮帮我。

我想创建一个新表(称为temp)。它合并了来自两个不同表中其他两个列的信息。

Code So far

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

你能指出我做错了什么吗?(欢迎任何帮助)

试试这个:

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 DBMS上吗?

UNIQUE约束违反错误是由于您的查询返回了您正在插入的表的键列的多行。

在您的示例中,TO_CHAR(trainFareDate, 'MM/DD/YYYY HH:MM:SS Q')将被插入键列。如果有两行具有相同的MM/DD/YYYY HH:MM:SS Q,您将得到此错误,假设您的DBMS真的在做"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列作为temp Table的主键,并使用newid()在联合的每一边生成值呢?

尝试在TO_CHAR()周围添加TRIM(),如:

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

我想我记得TO_CHAR有时会在你可能不期望的地方添加空格填充。如果空格填充导致总长度超过24个字符,那么当它进入临时表中的目标列时,它将被截断,这将使看起来存在重复,而实际上没有重复(即,它们仅在最后2或3个字符中不同,这些字符被截断)。

或者,将CHAR(24)列扩展为CHAR(1000)等更大的列,看看问题是否会消失。

最新更新