Таблица Oracle с только текущими записями;уменьшить количество дубликатов, используя максимум (дата) - PullRequest
1 голос
/ 21 апреля 2011

Мне нужно создать новую таблицу в oracle с только самой последней датой для каждой записи (шаг 1) и рассчитать дни между (шаг 2).

Ваши предложения очень ценятся:)))

Шаг 1: Сначала мне нужно найти максимум (Mod_date) для каждой записи из таблицы USERS.

ТАБЛИЦА: ПОЛЬЗОВАТЕЛИ

Имя ................ Mod_Date

Джейсон Мартин ....... 25 июля - 89

Аль Мэтьюз ....... 21-МАР-89

Джеймс Смит ........ 12-DEC-88

Роберт Блэк ....... 15-ЯНВ-84

Джейсон Мартин ....... 25-ИЮЛ-99

Аль Мэтьюз ....... 21-МАР-96

Джеймс Смит ........ 12-DEC-98

Роберт Блэк ....... 15-ЯНВ-94

* TABLE_DESIRED_RESULTS_step1

Имя ............... Макс. (Mod_Date)

Джейсон Мартин ....... 25-ИЮЛ-99

Аль Мэтьюз ....... 21-МАР-96

Джеймс Смит ........ 12-DEC-98

Роберт Блэк ....... 15-ЯНВ-94

Шаг 2: Рассчитать «Количество дней между Regist_Date и Mod_Date» и добавить его в таблицу.

ТАБЛИЦА: РЕГИСТРАЦИЯ

Имя ................ Regist_Date

Джейсон Мартин ........ 20-ИЮЛ-99

Аль Мэтьюз ........... 23-МАР-96

Роберт Блэк ......... 20-ЯНВ-94

* TABLE_DESIRED_RESULTS_step2

Имя ............... Макс. (Mod_Date) ..... Количество дней между Regist_Date и Mod_Date

Джейсон Мартин ...... 25-июл-99 .......... 5

Аль Мэтьюз ........ 21-МАР-96 .........- 2

Джеймс Смит ....... 12-DEC-98 .......... null

Роберт Блэк ...... 15-ЯНВ-94 ..........- 5

* Обратите внимание, что эти данные составлены, и у меня уже есть существующие союзы и объединения, к которым я должен добавить эту логику. Спасибо и хорошего дня!

1 Ответ

0 голосов
/ 21 апреля 2011

вот мой обновленный ответ с образцом.

Важно то, что ваш столбец даты имеет тип DATE. Вот таблицы и данные, соответствующие вашей спецификации.

CREATE TABLE USERS
   (
    ID_USER NUMBER(6)  NOT NULL,
    NAME VARCHAR2(64)  NOT NULL,
    MOD_DATE DATE  NOT NULL,
    CONSTRAINT PK_user PRIMARY KEY (ID_USER)
   ) ;

    INSERT INTO USERS VALUES (1,'Jason Martin',TO_DATE('25-07-1989','DD-MM-YYYY'));
    INSERT INTO USERS VALUES (2,'Al Mathews',TO_DATE('21-03-1989','DD-MM-YYYY'));
    INSERT INTO USERS VALUES (3,'James Smith',TO_DATE('12-12-1988','DD-MM-YYYY'));
    INSERT INTO USERS VALUES (4,'Robert Black',TO_DATE('15-01-1984','DD-MM-YYYY'));
    INSERT INTO USERS VALUES (5,'Jason Martin',TO_DATE('25-07-1999','DD-MM-YYYY'));
    INSERT INTO USERS VALUES (6,'Al Mathews',TO_DATE('21-03-1996','DD-MM-YYYY'));
    INSERT INTO USERS VALUES (7,'James Smith',TO_DATE('12-12-1998','DD-MM-YYYY'));
    INSERT INTO USERS VALUES (8,'Robert Black',TO_DATE('15-01-1994','DD-MM-YYYY'));


CREATE TABLE REGISTRATION
   (
    ID_REG NUMBER(6)  NOT NULL,
    NAME VARCHAR2(64)  NOT NULL,
    REGIST_DATE DATE  NOT NULL,
    CONSTRAINT PK_reg PRIMARY KEY (ID_REG)
   ) ;

    INSERT INTO REGISTRATION VALUES (1,'Jason Martin',TO_DATE('20-07-1999','DD-MM-YYYY'));
    INSERT INTO REGISTRATION VALUES (2,'Al Mathews',TO_DATE('23-03-1996','DD-MM-YYYY'));
    INSERT INTO REGISTRATION VALUES (3,'Robert Black',TO_DATE('20-01-1994','DD-MM-YYYY'));

Первый шаг

   CREATE  TABLE TABLE_DESIRED_RESULTS_step1
   AS ( 
   SELECT
         u.NAME
        , max(u.MOD_DATE) as "maxi"
       FROM USERS u
       GROUP BY u.NAME);

второй шаг

CREATE TABLE TABLE_DESIRED_RESULTS_step2 
AS (
SELECT 
    t.NAME 
    ,t."maxi"
    , (t."maxi" - r.REGIST_DATE ) as "Nbdays bw RegD and Mod_D"
FROM TABLE_DESIRED_RESULTS_step1 t LEFT OUTER JOIN REGISTRATION r 
ON t.NAME = r.NAME);

Хитрость в том, что LEFT OUTER JOIN допускает нулевое значение, если нет совпадения с объединением.


Но меня беспокоит дизайн базы данных. Если у вас есть 2 пользователя с одинаковым именем, вы объедините 2 человека в одного. Вот решение, использующее идентификаторы и выполняющее соединение по идентификаторам.

CREATE TABLE USERS
   (
    ID_USER NUMBER(6)  NOT NULL,
    NAME VARCHAR2(64)  NOT NULL,
    CONSTRAINT PK_user PRIMARY KEY (ID_USER)
   ) ; 

CREATE TABLE MOD_USERS
   (
    ID_MOD NUMBER(6)  NOT NULL,
    ID_USER NUMBER(6)  NOT NULL,
    CONSTRAINT PK_usermod PRIMARY KEY (ID_MOD)
   ) ; 

ALTER TABLE MOD_USERS ADD (
     CONSTRAINT FK_user_mod
          FOREIGN KEY (ID_USER)
               REFERENCES USERS (ID_USER));

CREATE TABLE REGISTRATION
   (
    ID_REG NUMBER(6)  NOT NULL,
    ID_USER VARCHAR2(64)  NOT NULL,
    REGIST_DATE DATE  NOT NULL,
    CONSTRAINT PK_reg PRIMARY KEY (ID_REG)
   ) ;

ALTER TABLE REGISTRATION ADD (
     CONSTRAINT FK_user_reg
          FOREIGN KEY (ID_USER)
               REFERENCES USERS (ID_USER))

;

Первый шаг

   CREATE  TABLE TABLE_DESIRED_RESULTS_step1
   AS ( 
   SELECT
         m.ID_USER , u.NAME
        , max(u.MOD_DATE) as "maxi"
       FROM USERS u INNER JOIN MOD_USERS m
           ON u.ID_USER = m.ID_USER
       GROUP BY m.ID_USER , u.NAME);

второй шаг

CREATE TABLE TABLE_DESIRED_RESULTS_step2 
AS (
SELECT 
    t.ID_USER , t.NAME 
    ,t."maxi"
    , (t."maxi" - r.REGIST_DATE ) as "Nbdays bw RegD and Mod_D"
FROM TABLE_DESIRED_RESULTS_step1 t LEFT OUTER JOIN REGISTRATION r 
ON t.ID_USER = r.ID_USER);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...