#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))