Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Составление запроса  [new]
Landgraf
Member

Откуда:
Сообщений: 278
Добрый день!

Подскажите, пожалуйста, по следующему вопросу:
Есть таблица в которой ведется лог по состоянию точек.

В таблице есть столбцы:
1. Дата изменения(DateChange);
2. Код точки(Code);
3. Состояние точки(Status) (0 - Открыт, 2 - Закрыт);

Пример таблицы:

DateChange -------------- Code --- Status
18.04.2009 14:15:21 --- AAA --- 0
18.04.2009 14:18:21 --- BBB --- 2
18.04.2009 15:37:08 --- AAA --- 2
18.04.2009 15:37:25 --- AAA --- 0
18.04.2009 15:47:08 --- BBB --- 0
18.04.2009 15:49:23 --- BBB --- 2


Задача следующая: Определить последнюю операцию проводившейся с точкой за определенный временной интервал.

Я предположил следующий алгоритм решения:

1. Группируем записи по коду точки (Code):

18.04.2009 14:15:21 AAA 0
18.04.2009 15:37:08 AAA 2
18.04.2009 15:37:25 AAA 0

18.04.2009 14:18:21 BBB 2
18.04.2009 15:47:08 BBB 0
18.04.2009 15:49:23 BBB 2

2. Теперь нужно из каждой группы отобрать время последнего изменения (DateChange) и вывести эти записи:

18.04.2009 15:37:25 AAA 0
18.04.2009 15:49:23 BBB 2

Код запроса:
Select 
    max(DateChange),
    DateChange, 
    Code,
    Decode(Status,0,'Открыт',2,'Закрыт')
From PointsLog  
 where 
    DateChange>'17.04.09'
    DateChange<='19.04.09'
    
Group by Code

К сожалению запрос отрабатывается с ошибкой - Not a GROUP BY expression.
Не могли бы подсказать, как правильно составить запрос?
19 апр 09, 12:49    [7084113]     Ответить | Цитировать Сообщить модератору
 Re: Составление запроса  [new]
аселъ...
Guest
например так
with q as (
select '01.01.09' dt, 'AAA' code, 2 status from dual
union all
select '02.01.09' dt, 'BBB' code, 0 status from dual
union all
select '03.01.09' dt, 'BBB' code, 2 status from dual
union all
select '04.01.09' dt, 'AAA' code, 0 status from dual
) 

select code, status from (select q.*, max(dt) over (partition by code) max_dt from q ) where dt = max_dt
19 апр 09, 13:07    [7084137]     Ответить | Цитировать Сообщить модератору
 Re: Составление запроса  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116094
Landgraf
Добрый день!

Подскажите, пожалуйста, по следующему вопросу:
Есть таблица в которой ведется лог по состоянию точек.

В таблице есть столбцы:
1. Дата изменения(DateChange);
2. Код точки(Code);
3. Состояние точки(Status) (0 - Открыт, 2 - Закрыт);

Пример таблицы:

DateChange -------------- Code --- Status
18.04.2009 14:15:21 --- AAA --- 0
18.04.2009 14:18:21 --- BBB --- 2
18.04.2009 15:37:08 --- AAA --- 2
18.04.2009 15:37:25 --- AAA --- 0
18.04.2009 15:47:08 --- BBB --- 0
18.04.2009 15:49:23 --- BBB --- 2


Задача следующая: Определить последнюю операцию проводившейся с точкой за определенный временной интервал.

Я предположил следующий алгоритм решения:

1. Группируем записи по коду точки (Code):

18.04.2009 14:15:21 AAA 0
18.04.2009 15:37:08 AAA 2
18.04.2009 15:37:25 AAA 0

18.04.2009 14:18:21 BBB 2
18.04.2009 15:47:08 BBB 0
18.04.2009 15:49:23 BBB 2

2. Теперь нужно из каждой группы отобрать время последнего изменения (DateChange) и вывести эти записи:

18.04.2009 15:37:25 AAA 0
18.04.2009 15:49:23 BBB 2

Код запроса:
Select 
    max(DateChange),
    DateChange, 
    Code,
    Decode(Status,0,'Открыт',2,'Закрыт')
From PointsLog  
 where 
    DateChange>'17.04.09'
    DateChange<='19.04.09'
    
Group by Code

К сожалению запрос отрабатывается с ошибкой - Not a GROUP BY expression.
Не могли бы подсказать, как правильно составить запрос?


Не разбирался в запросе, но ошибка налицо.
Все неагрегрированные поля в селекте обязательно
должны присутствовать в условии GROUP BY
19 апр 09, 13:08    [7084138]     Ответить | Цитировать Сообщить модератору
 Re: Составление запроса  [new]
Landgraf
Member

Откуда:
Сообщений: 278
dmidek


Не разбирался в запросе, но ошибка налицо.
Все неагрегрированные поля в селекте обязательно
должны присутствовать в условии GROUP BY



Получается не то что нужно. Он возвращает несколько записей для каждой группы. А должен возвратить только одну запись на каждую группу. Может как-нибудь с having поиграться?
19 апр 09, 13:30    [7084155]     Ответить | Цитировать Сообщить модератору
 Re: Составление запроса  [new]
spp
Guest
select code, 
         max(DateChange),
         max(status) keep (dense_rank last order by DateChange) status 
from PointsLog
group by code
19 апр 09, 13:50    [7084174]     Ответить | Цитировать Сообщить модератору
 Re: Составление запроса  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116094
Landgraf
dmidek


Не разбирался в запросе, но ошибка налицо.
Все неагрегрированные поля в селекте обязательно
должны присутствовать в условии GROUP BY



Получается не то что нужно. Он возвращает несколько записей для каждой группы. А должен возвратить только одну запись на каждую группу. Может как-нибудь с having поиграться?


А ну тогда у Вас обычная задача, одна из саамых популярных на форуме
"Показать строку с максимальным /минимальным параметром"
Решается например с подзапросом , определеяющим максимум
или с FIRST/LAST или с ROW_NUMBER() over ... rn .... where rn = 1

Форум наводнен такими задачами. Без преувеличения, сложно отыскать день,
когда их нет.
19 апр 09, 13:50    [7084175]     Ответить | Цитировать Сообщить модератору
 Re: Составление запроса  [new]
Landgraf
Member

Откуда:
Сообщений: 278
Спасибо за наставления! Сделал вот так:

select Status, Code from
(Select 
    DateChange, 
    Code,
    Decode(Status,0,'Открыт',2,'Закрыт') Status,
    ROW_NUMBER() over (partition by Code order by DateChange desc) PP
From PointsLog  
 where 
    DateChange>'17.04.09'
    DateChange<='19.04.09'
)   
Where PP=1
19 апр 09, 16:57    [7084431]     Ответить | Цитировать Сообщить модератору
 Re: Составление запроса  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116094
Landgraf
Спасибо за наставления! Сделал вот так:

select Status, Code from
(Select 
    DateChange, 
    Code,
    Decode(Status,0,'Открыт',2,'Закрыт') Status,
    ROW_NUMBER() over (partition by Code order by DateChange desc) PP
From PointsLog  
 where 
    DateChange>'17.04.09'
    DateChange<='19.04.09'
)   
Where PP=1


Да.
Только дам еще один совет. Никогда не полагайтесь на неявные
преобразования дат. Всегда задавайте дату явно
to_date('17.04.09','DD.MM.RR')
19 апр 09, 20:43    [7084726]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить