Получение данных из базы данных на основе системной даты и времени - PullRequest
0 голосов
/ 22 февраля 2012

Не могли бы вы дать совет или предоставить какое-либо решение, как решить приведенную ниже проблему:

таблица заказов:

order id   order_name  order_date
1          pizza       20-feb-2012
2          burger      17-feb-2012

таблица order_state

order_id     order_state     order_state_date          order_state_time
1             initiated      20-feb-2012               12:29:11:203
1             processed      21-feb-2012               12:29:12:112
1             cancelled      21-feb-2012               12:29:11:311
2             initiated      17-feb-2012               12:11:10:201
2             processed      18-feb-2012               12:01:01:301
2             cancelled      19-feb-2012               12:29:59:300 

Если я запрашиваю в понедельник, я должен проверить последние 3 дня, т.е. пятницу, субботу и воскресенье. Так что я могу получить вторую запись, если я запрашиваю сегодня, я могу получить первую запись, в обоих случаях отмененная запись, я должен иметь возможность извлекать на основе данных и времени.

Ниже Sql дает системную дату и время на основе дня:

select decode(TRIM(to_char(SYSDATE,'Day')),'Monday','3','1') from dual

Результат, если я запрашиваю напонедельник в 12:30 или 12: 29: 59: 299

order_id   order_state    order_name  order_state_date   order_state_time

2          canceled       burger      19-feb-2012         12:29:59:300

Результат, если я сделаю запрос сегодня в 12: 29: 10: 311 вечера

order_id   order_state    order_name  order_state_date   order_state_time

    1          canceled       pizza      21-feb-2012         12:29:59:300

Спасибо,

Chaitu

1 Ответ

1 голос
/ 22 февраля 2012

Трудно точно следовать тому, что вы ищете, и ваши данные и результаты местами кажутся противоречивыми; Я думаю, что вы хотите использовать аналитические функции для получения последнего состояния каждого заказа, но только если последнее изменение в заказе было за последние три дня - с точностью до миллисекунды?

Использование CTE для генерации данных образца:

with orders as (
select 1 as order_id, 'pizza' as order_name, '20-feb-2012' as order_date
    from dual
union all select 2, 'burger', '17-feb-2012' from dual
),
order_state as (
select 1 as order_id, 'initiated' as order_state, '20-feb-2012' as
    order_state_date, '12:29:11:203' as order_state_time from dual
union all select 1, 'processed', '21-feb-2012', '12:29:12:112' from dual
union all select 1, 'cancelled', '21-feb-2012', '12:29:11:311' from dual
union all select 2, 'initiated', '17-feb-2012', '12:11:10:201' from dual
union all select 2, 'processed', '18-feb-2012', '12:01:01:301' from dual
union all select 2, 'cancelled', '19-feb-2012', '12:29:59:300' from dual
)
-- actual query starts here
select order_id, order_state, order_state_date, order_state_time
from (
    select o.order_id,
        first_value(os.order_state)
            over (partition by os.order_id
                order by os.order_state_timestamp desc) as order_state,
        to_char(max(os.order_state_timestamp) over (partition by os.order_id),
            'DD-mon-YYYY') as order_state_date,
        to_char(max(os.order_state_timestamp) over (partition by os.order_id),
            'HH24:MI:SS:FF3') as order_state_time,
        max(os.order_state_timestamp) over (partition by os.order_id)
            as last_order_state_timestamp,
        row_number() over (partition by os.order_id order by os.order_id) as rn
    from orders o
    join (select order_id, order_state,
        to_timestamp(order_state_date ||' '|| order_state_time,
            'DD-mon-YYYY HH24:MI:SS:FF3') as order_state_timestamp
        from order_state) os
    on os.order_id = o.order_id
)
where rn = 1
and last_order_state_timestamp > systimestamp - interval '3' day;

  ORDER_ID ORDER_STA ORDER_STATE_DATE     ORDER_STATE_TIME
---------- --------- -------------------- ------------------
         1 processed 21-feb-2012          12:29:12:112

Ваши ожидаемые результаты имеют cancelled, но значения даты / времени для штатов выглядят неверно.

Если вы хотите показать заказы, созданные за последние три дня, а не только те, которые были обновлены, то вам нужно получить min() вместо max() отметку времени и отфильтровать ее.


Похоже, вас не интересует исправление модели для использования правильных типов столбцов даты / времени, так что это, очевидно, не имеет значения ...

Хранение даты и времени в отдельных полях делает это намного сложнее, чем нужно, и я не могу придумать какой-либо веской причины для этого. Если это сделано только потому, что поле DATE не содержит миллисекунд, используйте вместо этого поле TIMESTAMP. Я пытался минимизировать боль, преобразовав ее на лету в подзапросе, но это все еще не очень хорошая модель. Если у вас есть одно поле order_state_timestamp вместо отдельных полей даты / времени, запрос может выглядеть примерно так:

select order_id, order_state,
    to_char(last_order_state_timestamp, 'DD-mon-YYYY HH24:MI:SS:FF3')
    as order_state_timestamp
from (
    select o.order_id,
        first_value(os.order_state)
            over (partition by os.order_id
                order by os.order_state_timestamp desc) as order_state,
        max(os.order_state_timestamp) over (partition by os.order_id)
            as last_order_state_timestamp,
        row_number() over (partition by os.order_id order by os.order_id) as rn
    from orders o
    join order_state os on os.order_id = o.order_id
)
where rn = 1
and last_order_state_timestamp > systimestamp - interval '3' day;

что немного менее неприятно.


Редактировать: Исходя из комментария к вашему предыдущему / повторному вопросу , вы хотите, чтобы количество дней, которые вы оглядываетесь назад, варьировалось в зависимости от текущего дня. Это не очевидно из любого вопроса. Вы можете сделать это с помощью:

and last_order_state_timestamp > systimestamp
    - numtodsinterval(decode(to_char(sysdate, 'D'), '1', 3, 1), 'DAY');

Но вы должны быть осторожны с настройками NLS; результат to_char(sysdate, 'D') в понедельник здесь 1, но может быть 0 или что-то еще там, где вы находитесь. См. this , особенно комментарий к элементу D.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...