Текущее время: Вс, июн 22 2025, 13:38

Часовой пояс: UTC + 3 часа


Правила форума


ВНИМАНИЕ!

Вопросы по SAP Query и Quick View - сюда



Начать новую тему Ответить на тему  [ Сообщений: 25 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Как максимально быстро и изящно сделать group by по максимальному времени создания?
СообщениеДобавлено: Чт, окт 29 2015, 12:12 
Гуру-модератор
Гуру-модератор
Аватара пользователя

Зарегистрирован:
Вт, май 17 2005, 13:35
Сообщения: 4871
Откуда: Москва
Пол: Мужской
Коллеги, интересно ваше мнение, как лучше всего решить такую задачку.

Имеем таблицу zdbtab в БД:
MATNR - ключ, номер товара
DOCNAM - ключ, номер документа
CRETIME - не ключ, временной штамп создания документа.

Задача: имеем список товаров lt_matnr, надо из таблицы zdbtab для каждого товара выбрать номер документа с максимальным временем создания.

_________________
Удача - результат нашего желания (© А. Нортон)


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как максимально быстро и изящно сделать group by по максимальному времени создания?
СообщениеДобавлено: Чт, окт 29 2015, 12:28 
Почетный гуру
Почетный гуру

Зарегистрирован:
Пт, дек 04 2009, 12:52
Сообщения: 219
нет возможности проверить, но вроде, должно отработать:
Code:
SORT lt_matnr BY matnr docnam cretime DESCENDING .
DELETE ADJACENT DUPLICATES FROM lt_matnr COMPARING matnr docnam .


Принять этот ответ
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: Как максимально быстро и изящно сделать group by по максимальному времени создания?
СообщениеДобавлено: Чт, окт 29 2015, 13:00 
Почетный гуру
Почетный гуру
Аватара пользователя

Зарегистрирован:
Чт, сен 09 2004, 07:32
Сообщения: 777
Откуда: Москва
Пол: Мужской
Так тоже прикольно :lol: (по смыслу таблица подходит для теста):
Code:
  DATA: lt_cdhdr TYPE STANDARD TABLE OF cdhdr.

  SELECT DISTINCT objectclas objectid udate
    INTO CORRESPONDING FIELDS OF TABLE lt_cdhdr
    FROM cdhdr
    WHERE udate = sy-datum
    ORDER BY objectclas objectid.

  SELECT objectclas objectid changenr
    INTO CORRESPONDING FIELDS OF TABLE lt_cdhdr
    FROM cdhdr
    FOR ALL ENTRIES IN lt_cdhdr
    WHERE udate    = lt_cdhdr-udate
      AND changenr = ( SELECT MAX( changenr )
                         FROM cdhdr
                         WHERE objectclas = lt_cdhdr-objectclas
                           AND objectid   = lt_cdhdr-objectid
                           AND udate      = lt_cdhdr-udate )
    .


Про оптимальность выборки тут речи не идет... :lol:

_________________
"Прежде чем сделать что-то, подумай, к чему это может привести..."


Принять этот ответ
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: Как максимально быстро и изящно сделать group by по максимальному времени создания?
СообщениеДобавлено: Чт, окт 29 2015, 13:10 
Гуру-модератор
Гуру-модератор
Аватара пользователя

Зарегистрирован:
Вт, май 17 2005, 13:35
Сообщения: 4871
Откуда: Москва
Пол: Мужской
Бородин Игорь, насколько я понял, вы предлагаете выбрать из БД по списку товаров документы за все даты и уже на сервере приложений обработать табличку.
При наличии тысяч документов на один товар и индекса по matnr CRETIME в таблице, это явно не лучший способ.

nicky555, я так и написал, но результат отличался от ожиданий: для каждой порции товаров система находила максимальное время выгрузки в подселекте и уже его применяла к основному селкту.
Возможно, виноваты примененные без полного осознания хинты:
Code:
                %_HINTS ORACLE '&max_blocking_factor 100&'
                           ORACLE '&max_in_blocking_factor 100&'.

_________________
Удача - результат нашего желания (© А. Нортон)


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как максимально быстро и изящно сделать group by по максимальному времени создания?
СообщениеДобавлено: Чт, окт 29 2015, 13:35 
Почетный гуру
Почетный гуру
Аватара пользователя

Зарегистрирован:
Чт, сен 09 2004, 07:32
Сообщения: 777
Откуда: Москва
Пол: Мужской
Хинты здесь не нужны - они регулируют построение запроса по блокам записей таблицы. Даже затрудняюсь предположить, как они будут влиять на приведенную конструкцию с подзапросом.
А смысл выборки до безобразия прост - для каждой записи выбранной в первом селекте выбирается граничное значение (SubSelect), которое используется в результирующем селекте.
Возможно, коллеги, сведущие в Oracle (или какая у вас СУБД), подскажут конструкцию на Native SQL? :roll: Это, наверное, будет круче и быстрее.

_________________
"Прежде чем сделать что-то, подумай, к чему это может привести..."


Принять этот ответ
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: Как максимально быстро и изящно сделать group by по максимальному времени создания?
СообщениеДобавлено: Чт, окт 29 2015, 13:47 
Почетный гуру
Почетный гуру

Зарегистрирован:
Пт, дек 04 2009, 12:52
Сообщения: 219
извиняюсь, неправильно прочитал
LKU написал:
Задача: имеем список товаров lt_matnr...
думал, что lt_matnr и есть внутр.таблица с выбранными данными.
Тогда, или как Николай сказал, или таким образом:
Code:
LOOP AT lt_matnr INTO ls_matnr .
   SELECT *
     INTO TABLE lt_zdbtab_tmp
     FROM zdbtab
    WHERE matnr EQ ls_matnr-matnr .
   CHECK sy-subrc EQ 0 .

   SORT lt_zdbtab_tmp BY cretime DESCENDING .
   READ TABLE lt_zdbtab_tmp INTO ls_zdbtab INDEX 1 .

   APPEND ls_zdbtab TO lt_zdbtab .
ENDLOOP .


Последний раз редактировалось Бородин Игорь Пт, окт 30 2015, 11:59, всего редактировалось 2 раз(а).

Принять этот ответ
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: Как максимально быстро и изящно сделать group by по максимальному времени создания?
СообщениеДобавлено: Чт, окт 29 2015, 14:42 
Гуру-модератор
Гуру-модератор
Аватара пользователя

Зарегистрирован:
Вт, май 17 2005, 13:35
Сообщения: 4871
Откуда: Москва
Пол: Мужской
nicky555 написал:
Хинты здесь не нужны - они регулируют построение запроса по блокам записей таблицы. Даже затрудняюсь предположить, как они будут влиять на приведенную конструкцию с подзапросом.
А смысл выборки до безобразия прост - для каждой записи выбранной в первом селекте выбирается граничное значение (SubSelect), которое используется в результирующем селекте.
Возможно, коллеги, сведущие в Oracle (или какая у вас СУБД), подскажут конструкцию на Native SQL? :roll: Это, наверное, будет круче и быстрее.



Провел эксперимент - важно чтобы в основном запросе все ограничения where использовали передачу параметра из таблицы FAE. Если хотя бы одно ограничение задано константой - в подзапросе максимального времени товары объединяются пачкой через IN, что ломает весь смысл. Вот такой вот очередной прикол FAE.

В Oracle да, была какая-то фича, позволяющая выбрать данные одним запросом group by, но я не знаю как в native sql подать на вход внутреннюю табличку значений lt_matnr, это только FAE умеет.

_________________
Удача - результат нашего желания (© А. Нортон)


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как максимально быстро и изящно сделать group by по максимальному времени создания?
СообщениеДобавлено: Чт, окт 29 2015, 16:17 
Гуру-модератор
Гуру-модератор
Аватара пользователя

Зарегистрирован:
Вт, май 17 2005, 13:35
Сообщения: 4871
Откуда: Москва
Пол: Мужской
По поводу Native SQL наверное сработало бы что-нибудь вроде:
Code:
select max(docnr) KEEP (DENSE_RANK LAST ORDER BY CRETIME )
from zdbtab group by matnr
where matnr in (подать на вход lt_matnr)

_________________
Удача - результат нашего желания (© А. Нортон)


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как максимально быстро и изящно сделать group by по максимальному времени создания?
СообщениеДобавлено: Пт, окт 30 2015, 05:03 
Специалист
Специалист

Зарегистрирован:
Вт, июн 10 2014, 09:41
Сообщения: 180
А как-нибудь так работает?

Code:
  SELECT matnr docnam MAX( cretime ) AS cretime
    INTO CORRESPONDING FIELDS OF TABLE lt_zdbtab
    FROM zdbtab
    WHERE matnr IN lr_matnr
    GROUP BY matnr docnam cretime
    HAVING cretime = ( SELECT MAX( cretime )
                     FROM zdbtab AS tab
                     WHERE tab~matnr = zdbtab~matnr
                       AND tab~docnam = zdbtab~docnam )
  .


Ну и если скорости ещё захочется, то добавить индекс по полям matnr docnam cretime.


Принять этот ответ
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: Как максимально быстро и изящно сделать group by по максимальному времени создания?
СообщениеДобавлено: Пт, окт 30 2015, 11:40 
Гуру-эксперт
Гуру-эксперт
Аватара пользователя

Зарегистрирован:
Ср, ноя 03 2004, 14:51
Сообщения: 1912
Откуда: КраснАдар
Пол: Мужской
Может быть есть смысл добавить в эту табличку поле с индикатором "Активно" и немного подредактировать логику ее заполнения и обновления? Это конечно не спортивно, в плане темы топика, но работать будет железно.

PS
Либо добавить табличку:
MATNR - ключ, номер товара
DOCNAM - не ключ, номер документа
и параллельно с первой заполнять.


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как максимально быстро и изящно сделать group by по максимальному времени создания?
СообщениеДобавлено: Пт, окт 30 2015, 11:57 
Гуру-модератор
Гуру-модератор
Аватара пользователя

Зарегистрирован:
Вт, май 17 2005, 13:35
Сообщения: 4871
Откуда: Москва
Пол: Мужской
Второй вариант с отдельной табличкой (по сути - материализованный view) - это уж очень круто для такой задачи.

Первый вариант неплохой, но в реальной жизни задача стоит найти не просто последнюю выгрузку за все времена, а последнюю относительно какой-то даты.
Можно подход дополнить (в каждой следующей по времени строке хранить ссылку на номер предыдущей), тогда будет работать.
Получается, у нас будет признак последнего по времени документа, при вставке нового документа мы по этому признаку его находим, признак снимаем у старого документа, ставим у нового и прописываем в строке с новым документом номер старого.

Сложновато и есть риск неконсистентности (например, последний документ взяли и просто удалили :) ), но выборки потом будут быстрее работать, это точно

_________________
Удача - результат нашего желания (© А. Нортон)


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как максимально быстро и изящно сделать group by по максимальному времени создания?
СообщениеДобавлено: Пт, окт 30 2015, 12:00 
Гуру-модератор
Гуру-модератор
Аватара пользователя

Зарегистрирован:
Вт, май 17 2005, 13:35
Сообщения: 4871
Откуда: Москва
Пол: Мужской
Для информации - пока я остановился на варианте nicky555 с FAE и подзапросом.
В принципе, работает и вполне быстро (так как позапрос выполняется целиком по индексу, а потом идет доступ к основной таблице по первичному ключу).

_________________
Удача - результат нашего желания (© А. Нортон)


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как максимально быстро и изящно сделать group by по максимальному времени создания?
СообщениеДобавлено: Пн, ноя 02 2015, 18:04 
Специалист
Специалист

Зарегистрирован:
Чт, ноя 23 2006, 17:37
Сообщения: 197
Откуда: Москва
Пол: Мужской
Если я правильно понял вопрос, то:

Code:
        SELECT a~col1 a~date
        FROM table1 AS a
        INTO TABLE lt_table1
        WHERE a~col1 = 'COL1'
           AND a~date =
            ( SELECT MAX( b~date ) FROM table1 AS b
              WHERE b~col1 = a~col1
                AND b~date BETWEEN lv_date_beg AND lv_date_end ).


Такой селект выбирает для каждой группы (table1-col1) максимальную дату (table1-date) и получает значение col1, соответствующее максимальной дате для группы


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как максимально быстро и изящно сделать group by по максимальному времени создания?
СообщениеДобавлено: Пн, ноя 02 2015, 18:23 
Гуру-модератор
Гуру-модератор
Аватара пользователя

Зарегистрирован:
Вт, май 17 2005, 13:35
Сообщения: 4871
Откуда: Москва
Пол: Мужской
Ну да, только на входе у меня не одно значение col1 = 'COL1', а целый список в dj внутренней табличке lt_matnr, т.е. нужно либо применять цикл, либо FAE, либо преобразовывать в ranges, но следить чтобы не упало в дамп из-за превышения размера селекта.

_________________
Удача - результат нашего желания (© А. Нортон)


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Как максимально быстро и изящно сделать group by по максимальному времени создания?
СообщениеДобавлено: Вт, ноя 03 2015, 12:55 
Специалист
Специалист

Зарегистрирован:
Чт, ноя 23 2006, 17:37
Сообщения: 197
Откуда: Москва
Пол: Мужской
Ну, с выборкой, адаптированной под FOR ALL ENTRIES у меня сработало:

Code:
  SELECT a~matnr a~docnum a~cretime
  INTO CORRESPONDING FIELDS OF TABLE lt_doctab
  FROM table1 AS a
  FOR ALL ENTRIES IN lt_matnr
  WHERE a~matnr = lt_matnr-table_line
    AND a~cretime =
        ( SELECT MAX( b~cretime )
          FROM table1 AS b
          WHERE b~matnr = a~matnr
            AND b~docnum = a~docnum ).


Принять этот ответ
Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 25 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB