-4

Oracle に TIME DIMENSION を入力したいのですが、テーブルの粒度は 1 分/レコードです。したがって、合計レコードは 60*24 になります。このテーブルに入力するための挿入ステートメントを書くのを手伝ってください

CREATE TABLE TIME_DIM (
    TIME_KEY NUMBER(10) CONSTRAINT NN_TIME_KEY NOT NULL,
    TIME_DESC VARCHAR2(20),
    TIME_IN24_NAME VARCHAR2(20),
    TIME_HOUR24_MINUTE VARCHAR2(40),
    TIME_HOUR_NAME VARCHAR2(10),
    TIME_MINUTE_AMPM VARCHAR2(10),
    TIME_HOUR NUMBER,
    TIME_HOUR24 NUMBER,
    TIME_MINUTE NUMBER,
    TIME_SECOND NUMBER,
    TIME_AMPM_CODE VARCHAR2(2),
    PRIMARY KEY (TIME_KEY)
);

CREATE OR REPLACE TRIGGER TRG_TIME_DIM
BEFORE INSERT ON TIME_DIM FOR EACH ROW
BEGIN
  SELECT TIME_KEY_SEQ.NEXTVAL
  INTO :NEW.TIME_KEY
  FROM DUAL;
END;
/
COMMENT ON TABLE TIME_DIM IS 'The time dimension table support a business need down to the second for every minute in every hour of each day.';
COMMENT ON COLUMN TIME_DIM.TIME_KEY IS 'System generated surrogate key to uniquely identify the time dimension.';
COMMENT ON COLUMN TIME_DIM.TIME_DESC IS 'Time represented as hh:mm:ss with AM or PM.';
COMMENT ON COLUMN TIME_DIM.TIME_IN24_NAME IS 'Time represented as hh:mm:ss as reflected by a 24 hour clock.';
COMMENT ON COLUMN TIME_DIM.TIME_HOUR24_MINUTE IS 'Time represented as hh:mm as reflected by a 24 hour clock.';
COMMENT ON COLUMN TIME_DIM.TIME_HOUR_NAME IS 'The numerical version of the hour followed by AM or PM.';
COMMENT ON COLUMN TIME_DIM.TIME_MINUTE_AMPM IS 'The hour and minute represented as hh:mm followed by AM or PM.';
COMMENT ON COLUMN TIME_DIM.TIME_HOUR IS 'The numerical value of the hour based on a 12 hour clock.';
COMMENT ON COLUMN TIME_DIM.TIME_HOUR24 IS 'The numerical value of the hour based on a 24 hour clock.';
COMMENT ON COLUMN TIME_DIM.TIME_MINUTE IS 'The numerical value of the minute.';
COMMENT ON COLUMN TIME_DIM.TIME_SECOND IS 'The numerical value of the second.';
COMMENT ON COLUMN TIME_DIM.TIME_AMPM_CODE IS 'Indicates whether the time is morning or afternoon.';
4

1 に答える 1

4

これは、日付形式のマスクが異なるだけで、前の質問とほとんど同じではありませんか? ともかく...

insert into TIME_DIM (TIME_DESC,
    TIME_IN24_NAME,
    TIME_HOUR24_MINUTE,
    TIME_HOUR_NAME,
    TIME_MINUTE_AMPM,
    TIME_HOUR,
    TIME_HOUR24,
    TIME_MINUTE,
    TIME_SECOND,
    TIME_AMPM_CODE)
select to_char(t, 'HH:MI:SS AM'),
  to_char(t, 'HH24:MI:SS'),
  to_char(t, 'HH24:MI'),
  to_char(t, 'HH AM'),
  to_char(t, 'HH:MI AM'),
  to_number(to_char(t, 'HH'), '00'),
  to_number(to_char(t, 'HH24'), '00'),
  to_number(to_char(t, 'MI'), '00'),
  to_number(to_char(t, 'SS'), '00'),
  to_char(t, 'AM')
from (
  select trunc(sysdate) + (level - 1)/1440 as t
  from dual
  connect by level <= 1440
);

1,440 rows inserted.

そしてチェックする:

select * from time_dim order by time_key;

  TIME_KEY TIME_DESC            TIME_IN24_NAME       TIME_HOUR24_MINUTE                       TIME_HOUR_NAME TIME_MINUTE_AMPM  TIME_HOUR TIME_HOUR24 TIME_MINUTE TIME_SECOND TIME_AMPM_CODE
---------- -------------------- -------------------- ---------------------------------------- -------------- ---------------- ---------- ----------- ----------- ----------- --------------
         1 12:00:00 AM          00:00:00             00:00                                    12 AM          12:00 AM                 12           0           0           0 AM             
         2 12:01:00 AM          00:01:00             00:01                                    12 AM          12:01 AM                 12           0           1           0 AM             
...
      1439 11:58:00 PM          23:58:00             23:58                                    11 PM          11:58 PM                 11          23          58           0 PM             
      1440 11:59:00 PM          23:59:00             23:59                                    11 PM          11:59 PM                 11          23          59           0 PM             

ちなみに、ほとんどの列は不必要に幅が広くなっています。


connect by、1 日の分数である 1 から 1440 までのすべての数値を生成しています。を実行すると、それを確認できますselect level as l from dual connect by level <= 1440(level -1)/1440それは;で 1 日の分数に変わります。の代わりに-1から始まります。したがって、レベルがの場合、たとえば、 が得られます。これはです。01/14403736/14400.025

Oracleの日付演算では、このような 1 日の端数を別の日付に追加できます。これを追加するとtrunc(sysdate)、今朝の真夜中になりますが、固定の真夜中であれば何でも構いません。つまり、trunc(sysdate) + (level - 1)/1440は と同等2013-07-10 00:00:00 + 0.025です2013-07-10 00:36:00

内部選択により、今日は 1 分ごとの 1440 の間隔に分割されました。繰り返しますが、そのインナー全体を単独で実行することで、それを確認できますselect。挿入は、さまざまな列に要求したとおりにフォーマットされたこれらすべてを使用します。使用されるデータ形式マスクには、日、月、または年が含まれていないため、任意の基準日を使用できました。このシナリオでは、日付部分は事実上破棄されます。

それぞれ 1 秒の 86400 間隔が必要な場合、まったく同じロジックが適用されます。内部選択でより多くのより小さな間隔を生成する必要があるだけです。つまり、connect byより多くの値を生成する必要がありlevelます。あなたの書式マスクはすでに秒を記録しています - 現時点ではすべてゼロです。


OK、あきらめます... 86400 レコードすべてを 1 秒に 1 つずつ空のテーブルに挿入するには、内部選択の 2 つの 1440 番号を 86400 に変更するだけです。

...
from (
  select trunc(sysdate) + (level - 1)/86400 as t
  from dual
  connect by level <= 86400
);

うまくいけば、その理由はすでに明らかです。

テーブルに 1440 個の 1 分ごとのレコードが既に入力されており、何らかの理由でそれらをすべて削除したり、テーブルを切り捨てたりしてやり直すことができない場合は、同じものを使用して毎分 59 個の「不足している」レコードを挿入できます。メソッドですが、既に持っている値を除外するだけです-time_second値が0の値は事実上。

...
from (
  select trunc(sysdate) + (level - 1)/86400 as t
  from dual
  connect by level <= 86400
)
where t != trunc(t, 'MI');

フィルターは、生成された時刻を内部選択から除外しています。ここで、tはそれ自体に正確に等しく、分単位で切り捨てられます。もしtだったら00:01:42trunc(t, 'MI')なり 00:01:00、あなたはすでにその記録を持っています。したがって、それと、それと同様の 1439 の他のものはスキップされ、内部選択から生成された他の 84960 が挿入されます。time_secondこれにより、1 から 59 までのすべての値が得られます。

time_key値は順不同になりますが、おそらく問題にはなりません。その場合、完全な挿入を行う前に、切り捨て、場合によってはシーケンスもリセットする必要があります。

于 2013-07-09T14:00:10.950 に答える