SQL Oracle — получить последнюю запись за каждый месяц

#sql #oracle #stored-procedures #plsql

#sql #Oracle #хранимые процедуры #plsql

Вопрос:

У меня есть таблица, содержащая некоторые данные проверки. Каждый товар должен проверяться каждый месяц. Цель здесь — найти последнюю проверенную запись за каждый месяц.

Проверка таблицы:

INSPECTION_I ———INSPECTION_TS

200————————— 10/20/2011

201—————————-10/24/2011

202—————————-10/26/2011

Таблица Product_Inspection:

ИНСПЕКЦИЯ_I—————— ASSET_I

200————————————1000

201————————————2000

Таблица Box_Inspection

INSPECTION_I ———ASSET_I

202————————3000

Табличный продукт

ASSET_I———— АССОЦИИРОВАННЫЙ_БОКС_АССЕТ_И

1000—————————3000

ПОЛЕ таблицы:

ASSET_I———— ДРУГОЙ МАТЕРИАЛ

3000———————#####

Теперь в этом случае я хочу 201, а не 200. Я пытался выполнить MAX(to_char(inspection_ts, ‘мм / гггг’)), но это не помогает. Есть еще одна проблема. По какой-то причине я продолжаю получать декартово значение в случае, когда продукт или коробка проверяются два или более раз в месяц. Все, что я хочу, это одна проверка каждый месяц, и это должна быть последняя проверка за каждый месяц. Я действительно близок к ее получению, но если кто-то может помочь, я был бы очень признателен. Я смог сделать это с помощью вложенного курсора, но я этого не хочу.

Ответ №1:

Я обычно использую аналитические функции для выполнения такого рода запросов. Что-то вроде:

 with data as
(
    select 1 product_id, 100 inspection_id, to_date('09/04/2011', 'MM/DD/YYYY') inspection_date from dual union all
    select 1 product_id, 101 inspection_id, to_date('09/14/2011', 'MM/DD/YYYY') inspection_date from dual union all
    select 1 product_id, 103 inspection_id, to_date('10/04/2011', 'MM/DD/YYYY') inspection_date from dual union all
    select 1 product_id, 105 inspection_id, to_date('11/01/2011', 'MM/DD/YYYY') inspection_date from dual union all
    select 2 product_id, 102 inspection_id, to_date('09/24/2011', 'MM/DD/YYYY') inspection_date from dual union all
    select 2 product_id, 104 inspection_id, to_date('10/05/2011', 'MM/DD/YYYY') inspection_date from dual
)
select *
from 
(
    select
        product_id,
        inspection_id,
        inspection_date,
        row_number() over (
            partition by
                product_id,
                trunc(inspection_date, 'MM') -- Month
            order by
                inspection_date desc
        ) rn
    from
        data
)
where rn = 1 -- indicates last inspection date of the month for each product
 

Комментарии:

1. Эй, Крейг, я не работал с аналитическими функциями, но, похоже, на это определенно стоит обратить внимание. Просто чтобы вы знали, я также получаю входной параметр в своем SP и возвращаю один курсор, который я извлекаю на уровне Java DAO. Следовательно, это динамическая строка SQL. Если я пойду по этому пути, будет ли это интегрироваться с моим текущим SP?

2. Да, это должно работать для вашего SP, предполагая, что вы находитесь как минимум в 9i. Если у вас есть какие-либо вопросы о том, как заставить его работать, дайте мне знать.

Ответ №2:

используйте подзапрос

 Select [ColName List]
From TableName a
Where DateTimeColumname 
   = (Select Max(DateTimeColumnName)
      From TableName 
      Where DateTimeColumnName < 1 Last_Day(a.DateTimeColumnName))