2

PL/SQL で 2 つのテーブルから 2 つの列をマージしようとすると、非常に困難です。私はこれに午前 9 時から取り組んでいましたが、あきらめました。助けてください。

目的

新しいテーブルを作成したいと思います(一時と呼びます)。これにより、2 つの異なるテーブルの他の 2 つの列からの情報がマージされます。

コード ここまで

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

4 に答える 4

3

これを試して:

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'));
于 2011-04-08T19:23:01.720 に答える
1

奇妙なことに、UNION は重複を自動的に削除する必要があります。これは Oracle DBMS 上にありますか?

UNIQUE CONSTRAINT 違反エラーは、挿入先のテーブルのキー列に対してクエリが複数の行を返すことが原因です。

あなたの場合、 TO_CHAR(trainFareDate, 'MM/DD/YYYY HH:MM:SS Q') がキー列に挿入されます。同じ MM/DD/YYYY HH:MM:SS Q を持つ 2 つの行がある場合、DBMS が実際に "UNION ALL" を実行していると仮定すると、このエラーが発生します。

主キーに 2 番目の列を追加して、「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));
于 2011-04-08T19:21:39.890 に答える
0

制約に違反する同じ日時のバス運賃と時間運賃を持っている必要があります。一時テーブルの主キーとして GUID 列を追加し、newid() を使用してユニオンの両側に値を生成してみませんか。

于 2011-04-08T19:18:58.513 に答える
-1

次のように、TO_CHAR() の周りに TRIM() を追加してみてください。

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

TO_CHAR は、予期しない場所にスペースのパディングを追加することがあることを覚えていると思います。スペースの埋め込みによって合計の長さが 24 文字を超える場合、一時テーブルのターゲット列に入るときに切り捨てられます。最後の 2 ~ 3 文字だけが切り取られています)。

または、CHAR(24) 列を CHAR(1000) のような大きなものに拡張して、問題が解決するかどうかを確認します。

于 2011-04-08T20:00:57.447 に答える