Разделение по определенному значению, а затем по диапазону в Oracle - PullRequest
1 голос
/ 01 ноября 2019

У меня есть таблица со следующими столбцами:

CREATE TABLE CUST_HISTORY (
    ID          NUMBER,
    PRD_CNT     NUMBER,
    DATE_TO     DATE
)

Теперь я хотел бы применить следующую стратегию секционирования:

  • все значения, где DATE_TO = '9999-12-31 'должно быть назначено одному разделу с именем "p_max"
  • все остальные значения DATE_TO должны быть разбиты на месячные интервалы (от DATE_TO)

Любые подсказки?

Ответы [ 2 ]

3 голосов
/ 01 ноября 2019

С этот ответ :

CREATE TABLE CUST_HISTORY (
    ID          NUMBER,
    PRD_CNT     NUMBER,
    DATE_TO     DATE
)
PARTITION BY RANGE (date_to)
  INTERVAL (INTERVAL '1' MONTH)
  (PARTITION p_first VALUES LESS THAN ( DATE '2019-01-01' ) );

db <> fiddle

Если вы хотите, чтобы раздел был назван p_max затем вы можете использовать виртуальный столбец для преобразования значения DATE_TO из верхнего значения в низкое, чтобы вы могли назвать раздел и затем использовать интервалы диапазона:

CREATE TABLE CUST_HISTORY (
    ID               NUMBER,
    PRD_CNT          NUMBER,
    DATE_TO          DATE CHECK ( DATE_TO >= DATE '1900-01-01' ),
    remapped_date_to DATE
                     GENERATED ALWAYS AS
                     ( CASE WHEN date_to = DATE '9999-12-31' THEN DATE '0001-01-01' ELSE date_to END )
                     VIRTUAL
)
PARTITION BY RANGE (remapped_date_to)
  INTERVAL (INTERVAL '1' MONTH)
  (PARTITION p_max VALUES LESS THAN ( DATE '1900-01-01' ) );

дБ <>fiddle

или использование AUTOMATIC LIST разбиения (Oracle 12c или новее) с виртуальным столбцом:

CREATE TABLE CUST_HISTORY (
    ID          NUMBER,
    PRD_CNT     NUMBER,
    DATE_TO     DATE,
    month_to    DATE
                -- INVISIBLE
                GENERATED ALWAYS AS
                ( CASE WHEN date_to = DATE '9999-12-31' THEN date_to ELSE TRUNC( date_to, 'MM' ) END )
                VIRTUAL
)
PARTITION BY LIST ( month_to ) AUTOMATIC
  ( PARTITION p_max VALUES ( DATE '9999-12-31' ) );

db <> fiddle

(при желании вы также можете сделать виртуальный столбец INVISIBLE)

0 голосов
/ 04 ноября 2019

Решение с ежемесячным разбиением (соблюдайте функцию last_day):

CREATE TABLE CUST_HISTORY (
    ID          NUMBER,
    PRD_CNT     NUMBER,
    DATE_TO     DATE,
    month_to    DATE
                GENERATED ALWAYS AS
                ( CASE WHEN date_to = DATE '9999-12-31' THEN date_to ELSE TRUNC( last_day(date_to) ) END )
                VIRTUAL
)
PARTITION BY LIST ( month_to ) AUTOMATIC
  ( PARTITION p_max VALUES ( DATE '9999-12-31' ) );

DB <> FIDDLE

Спасибодля вдохновения @ mt0 !

...