AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
DAX
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 21.05.2022, 01:30   #1  
DesparioN is offline
DesparioN
Участник
 
60 / 12 (1) ++
Регистрация: 21.10.2014
Вложенный запрос (DAX2012)
Добрый день!

Продолжая эпопею с оптимизацией запросов, появилась потребность в получении значения не перебором, а единым запросом.

Необходимо сделать следующее:
1) сгруппировать таблицу по 2 полям
2) посчитать максимальное значение по полю 2, сгруппировав по полю 1

К сожалению на текущий момент в окружении нет квалифицированных специалистов, приходится делать своими силами, которые крайне ограничены по знаниям, как и время на реализацию

Возможно ли сделать подобный запрос в Аксапте?
Старый 21.05.2022, 07:35   #2  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,466 / 4344 (203) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от DesparioN Посмотреть сообщение
Возможно ли сделать подобный запрос в Аксапте?
да, чёрным запросом
https://github.com/mazzy-ax/SysResultSet

дополнительно поприсваивайте fieldnum и tablenum в какой-нибудь неиспользуемый контейнер в этом методе. тогда перекрестные ссылки покажут, что указанные поля и таблицы в этом методе используются.

но вопрос скорее надо ставить не "возможно ли?",
а "какое решение экономически целесообразно"?
с точки зрения поддержки, с точки зрения модифицируемости и дальнейшего развития системы.

например, стопудов ваши два пункта не последние, а часть какого-то большого алгоритма. в этом большом алгоритме наверняка определяются и входящие условия, и как будут использоваться результаты этого запроса. стопудов выяснится, что в алгоритме используется еще и "поле 3", "поле 4" и "поле N", из-за которых вам придется делать дополнительные выборки.
__________________
полезное на axForum, github, vk, coub.
За это сообщение автора поблагодарили: Raven Melancholic (5).
Старый 21.05.2022, 12:06   #3  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,775 / 5451 (187) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
В DAX2012 (и даже в Dax2009) можно создать view.
Сначала создаем View с двумя полями, основанный на Query, в котором по этим двум полям группировка.
Потом пишем запрос
X++:
 while select maxof(field2),Field1
From MyView
Group by field1
{
}
За это сообщение автора поблагодарили: mazzy (5), DesparioN (1).
Старый 21.05.2022, 16:24   #4  
sukhanchik is offline
sukhanchik
Moderator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,139 / 3216 (114) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Небольшие 5 копеек.
Если табличка большая по объёму (несколько миллионов записей), то будет критично, если по полям, перечисленным в условиях отбора (WHERE), условиях группировки (GROUP BY) и условиях сортировки (ORDER BY) нету хотя бы частично покрывающего (по полям, содержащие наиболее уникальные значения, можно не по всем полям) индекса.
Поэтому в идеале - все типы запросов к таблице нужно свести к ограниченному количеству и по ним построить рекомендуемые базой данных индексы.

Собственно поэтому количество полей в GROUP BY лучше зафиксировать и не расширять (т.е. если потребуется расширение - решать эту задачу не одним запросом, а несколькими)
Совет актуален в первую очередь для периодической выборки.
__________________
Возможно сделать все. Вопрос времени
Старый 23.05.2022, 08:46   #5  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
617 / 300 (12) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Добрый день. Для меня немного непонятно, почему нельзя опустить пункт 1?
Зачем сначала делать группировку по 2 полям, чтобы потом получить максимальное с группировкой - и всё это на базе тех же самых 2 полей?
Есть какой-то скрытый смысл?
__________________
// no comments
За это сообщение автора поблагодарили: ice (1).
Старый 23.05.2022, 09:29   #6  
DesparioN is offline
DesparioN
Участник
 
60 / 12 (1) ++
Регистрация: 21.10.2014
Да, будет разное количество. Условно на каждую пару полей приходится по 20-30 строк. Т.е. без второго пункта будет не 2 записи, 40-60.
Старый 23.05.2022, 09:30   #7  
DesparioN is offline
DesparioN
Участник
 
60 / 12 (1) ++
Регистрация: 21.10.2014
А я ведь главное сделал сразу вьюху, но так увлекся изучением программируемых полей, что забыл, что там можно группировать. Благодарю
Старый 23.05.2022, 09:57   #8  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,466 / 4344 (203) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от DesparioN Посмотреть сообщение
Да, будет разное количество.


Цитата:
Сообщение от DesparioN Посмотреть сообщение
программируемых полей
как всегда в программистских задачах:

помните, что группировка по полю без индекса - это Table scan.
т.е. вам нужно подумать не как запрограммировать в Аксапте универсальный запрос.
а о том, как сделать ваш код в целом быстрым и эффективным. возможно, стоит даже не ограничиться только SQL, а по-другому распределить нагрузку между SQL и AOS.

уверяю вас, "универсальные запросы по произвольным полям" - это зло.

лучше переделайте вашу схему данных.
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 23.05.2022 в 10:02.
За это сообщение автора поблагодарили: sukhanchik (4).
Старый 23.05.2022, 14:23   #9  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
617 / 300 (12) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Цитата:
Сообщение от DesparioN Посмотреть сообщение
Да, будет разное количество. Условно на каждую пару полей приходится по 20-30 строк. Т.е. без второго пункта будет не 2 записи, 40-60.
Вы меня не совсем правильно поняли, Что будет результатом без первого пункта?
Или может быть я вас не совсем так понял? Давайте разберем пример.
Допустим, вы хотите узнать время последней активности по всем клиентам и группируете CustTrans по полям AccountNum(1) и TransDate(2).

Пункт 1. Вы делаете группировку по AccountNum, TransDate
Пункт 2. Вы также делаете группировку по AccountNum, а по TransDate ищете максимальную дату.
Разве изменится что-то, если вы выкинете пункт 1 и оставите пункт 2?
__________________
// no comments
Старый 23.05.2022, 16:01   #10  
DesparioN is offline
DesparioN
Участник
 
60 / 12 (1) ++
Регистрация: 21.10.2014
Условие другое: требуется найти не максимальную дату, а максимальное количество разных дат.
За это сообщение автора поблагодарили: dech (1).
Старый 23.05.2022, 23:50   #11  
DesparioN is offline
DesparioN
Участник
 
60 / 12 (1) ++
Регистрация: 21.10.2014
Еще помучаю, если можно. Написал запрос.
В итоге, если:
1) взять COUNT(Field) order by Field DESC, то получается 2.
2) Если перебором, то получается 3
3) если в п.1 добавить фильтр по номенклатуре e которой реально 3, то получается 3.

С чем это может быть связано?

Для справки, если это может быть важно, Field - string
Старый 24.05.2022, 07:30   #12  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,775 / 5451 (187) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Цитата:
Сообщение от DesparioN Посмотреть сообщение
Еще помучаю, если можно. Написал запрос.
В итоге, если:
1) взять COUNT(Field) order by Field DESC, то получается 2.
2) Если перебором, то получается 3
3) если в п.1 добавить фильтр по номенклатуре e которой реально 3, то получается 3.
Все таки уточню задачу. Я так понимаю, у вас есть что-то типа таблицы товародвижений. Первое поле - некое ключевое поле (типа клиента или номенклатуры), второе поле - что-то считающееся транзакционным - может быть дата, может быть код номенклатуры (если первое поле - код клиента). Задача состоит в том чтобы для каждого значения первого (ключевого) поля, вывести число уникальных значений второго (транзакционного) поля. (типа - сколько раз грузили клиенту, или сколько разных номенклатур покупал клиент).
В таком случае, задача решается так:
1. Создается view1 по основной таблице, во вьюшке оба поля, по обоим полям стоит группировка.
2. Создается view2. View2 построено по view1, сделана группировка по ключевому полю (field1), поставлена функция count(recid) (второе поле тут строго говоря вообще не при делах, сount нужно делать по любому int64 полю, recId -наиболее очевидный кандидат).

Во view2 в итоге будут находится записи в которых для каждого значения ключевого поля во втором поле будет находится число уникальных значений транзакционного поля в оригинальной таблице.
Старый 24.05.2022, 08:53   #13  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
617 / 300 (12) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Цитата:
Сообщение от DesparioN Посмотреть сообщение
Еще помучаю, если можно. Написал запрос.
В итоге, если:
1) взять COUNT(Field) order by Field DESC, то получается 2.
2) Если перебором, то получается 3
3) если в п.1 добавить фильтр по номенклатуре e которой реально 3, то получается 3.

С чем это может быть связано?

Для справки, если это может быть важно, Field - string
Сортировка по агрегированному полю, а также отсутствующему в группировке не срабатывает.
Возможно стоит попробовать выполнение запроса на чистом SQL, без создания дополнительных вьюшек.
В этом случае можно воспользоваться ORDER BY N, где N - это номер поля, участвующего в выборке.
Note! Класс с вашим запросом должен исполняться на сервере.
__________________
// no comments
Старый 24.05.2022, 08:54   #14  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,388 / 1712 (64) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от DesparioN Посмотреть сообщение
1) взять COUNT(Field) order by Field DESC, то получается 2.
Вы наверное ожидаете что order by будет применён к результату агрегирующей функции? В Аксапте оно так не работает. Только если, как вам уже советовали, явно зафиксировать результат агрегации в виде View, а потом уже внешним по отношению к View запросом отсортировать результат
Старый 24.05.2022, 10:12   #15  
DesparioN is offline
DesparioN
Участник
 
60 / 12 (1) ++
Регистрация: 21.10.2014
Понял, принял. Благодарю.
Старый 24.05.2022, 18:17   #16  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,579 / 1113 (41) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Странно, что решение "в лоб" не рассматривается

1. Выборка с группировкой во временную таблицу
2. Выборка по временной таблице из п.1

View - это большие "накладные расходы" на сопровождение. Иногда нужно, конечно, но лучше обойтись
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 24.05.2022, 19:34   #17  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,466 / 4344 (203) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Странно, что решение "в лоб" не рассматривается
так задал вопрос топикстартер:

Цитата:
Сообщение от DesparioN Посмотреть сообщение
появилась потребность в получении значения не перебором, а единым запросом.
...
Возможно ли сделать подобный запрос в Аксапте?
__________________
полезное на axForum, github, vk, coub.
Старый 24.05.2022, 20:57   #18  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,579 / 1113 (41) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Так это решение и есть. Не перебором. Отличие только в том, что не один запрос, а два
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Statement, запрос (несколько) с транзакцией Pandasama DAX: Программирование 4 08.08.2016 10:39
Как класс->запрос->форма. Как такое создать? kitty DAX: Программирование 16 09.09.2014 12:52
DAX2012 - перепоставки по закупкам Starling DAX: Функционал 2 18.03.2014 13:56
Вложенный запрос SQL с помощью великого Query user_ax DAX: Программирование 9 07.10.2013 14:00
Почему join запрос разбивается на подзапросы!? 3oppo DAX: Программирование 59 28.06.2007 11:52
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 07:16.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.