Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / FIRST_VALUE - учусь / 9 сообщений из 9, страница 1 из 1
26.08.2016, 09:06:22
    #39298365
dmdmdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FIRST_VALUE - учусь
Скажем прямо, аналитику использую редко, потому и умею ее плохо.
Задача - собрать статистику по карточкам товаров. Простейшая задача для тренировки - когда и кем создана.
Напрашивается FIRST_VALUE из журнала, но в group by ее указывать нельзя, как я понял.
Получилось вот так коряво.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select article, name, min(created), min(who)
  from (
select c.article, c.name, first_value(l.eventtime) over(partition by l.article order by l.eventtime) created, first_value(l.username) over(partition by l.article order by l.eventtime) who
  from SMCARD c, SMCardSecurityLog l
 where c.article = l.article
       )
 group by article, name
 having min(created) >= to_date('01.08.2016', 'dd.mm.yyyy')
 order by name
  



Наставьте на путь истинный. Как лучше?
...
Рейтинг: 0 / 0
26.08.2016, 09:13:13
    #39298372
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FIRST_VALUE - учусь
dmdmdmаналитику использую редкоА здесь ониа и не нужна.
RTFM/STFF FIRST/LAST (KEEP)
...
Рейтинг: 0 / 0
26.08.2016, 09:29:02
    #39298383
dmdmdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FIRST_VALUE - учусь
Написал, как понял.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
select article, name, created, who
  from (
select c.article, c.name,
       min(l.eventtime) keep (dense_rank first order by l.eventtime) created,
       min(l.username) keep (dense_rank first order by l.eventtime) who
  from SMCARD c, SMCardSecurityLog l
 where c.article = l.article
 group by c.article, c.name
       )
 where created >= to_date('01.08.2016', 'dd.mm.yyyy')
 order by name 
...
Рейтинг: 0 / 0
26.08.2016, 09:31:16
    #39298385
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FIRST_VALUE - учусь
Этажность не обязательна.
...
Рейтинг: 0 / 0
26.08.2016, 09:36:58
    #39298389
dmdmdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FIRST_VALUE - учусь
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select c.article, c.name,
       min(l.eventtime) keep (dense_rank first order by l.eventtime) created,
       min(l.username) keep (dense_rank first order by l.eventtime) who
  from SMCARD c, SMCardSecurityLog l
 where c.article = l.article
 group by c.article, c.name
 having min(l.eventtime) >= to_date('01.08.2016', 'dd.mm.yyyy')
 order by c.name 



Можно еще лучше? :)
...
Рейтинг: 0 / 0
26.08.2016, 09:54:13
    #39298405
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FIRST_VALUE - учусь
dmdmdm
Код: plsql
1.
min(l.eventtime) keep (dense_rank first order by l.eventtime) created,

Можно еще лучше
...
Рейтинг: 0 / 0
29.08.2016, 06:05:51
    #39299302
AnSi_Sr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FIRST_VALUE - учусь
dmdmdm
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select c.article, c.name,
       min(l.eventtime) keep (dense_rank first order by l.eventtime) created,
       min(l.username) keep (dense_rank first order by l.eventtime) who
  from SMCARD c, SMCardSecurityLog l
 where c.article = l.article
 group by c.article, c.name
 having min(l.eventtime) >= to_date('01.08.2016', 'dd.mm.yyyy')
 order by c.name 



Можно еще лучше? :)

В такой форме записи не нравится то, что групповая функция по сути оперирует с одним значением securitylog.username. При беглом взгляде сначала показалось, что ошибка в запросе - выберется минимальное имя пользователя.

Обычно в таких случаях использую row_number(), с секционированием по идентификатору сущности (card.article), обратной сортировкой по дате изменения (securitylog.eventtime) и внешним запросом на выборку первой строки. При этом можно любые поля из card, securitylog выбирать без дополнительных max/min и группировок по выбранным полям.
...
Рейтинг: 0 / 0
29.08.2016, 07:08:57
    #39299307
sententia
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FIRST_VALUE - учусь
AnSi_SrОбычно в таких случаях использую row_number()Группировка может быть эффективнее аналитической сортировки, так как в некоторых случая требует меньше памяти и может использовать hash-алгоритм.
Для детерминизма групповым first/lastам нужно добавлять в сортировку уникальный ключ.
...
Рейтинг: 0 / 0
29.08.2016, 07:38:59
    #39299310
dmdmdm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FIRST_VALUE - учусь
AnSi_Sr, спасибо, освоил.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select article, name, eventtime, username
  from (
select c.article, c.name, l.eventtime, l.username,
       row_number() over (partition by c.article order by l.eventtime desc, l.recid desc) rn
  from SMCARD c, SMCardSecurityLog l
 where c.article = l.article
       )
 where rn = 1
   and eventtime > to_date('25.08.2016', 'dd.mm.yyyy')
 order by name



Про выбор из эффективности и легкости чтения соглашусь - если эффективность выше не в разы, а на проценты, выбираю легкость чтения. В конце концов, есть важнейший ресурс - время. Можно его потратить и сделать эффективно и легкочитаемо.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / FIRST_VALUE - учусь / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]