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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 16.11.2006, 16:16   #1  
Sada is offline
Sada
Программатор
Аватар для Sada
 
1,450 / 153 (8) ++++++
Регистрация: 29.03.2005
Адрес: Толи Барнаул, толи Москва
Цитата:
Сообщение от Eldar9x Посмотреть сообщение
кстати, payTrans.amount действительно используется далее, но какая это запись данной таблицы?
это сумма по нескольким записям
Старый 16.11.2006, 16:19   #2  
Eldar9x is offline
Eldar9x
MCTS
Аватар для Eldar9x
Oracle
MCBMSS
 
1,064 / 166 (8) ++++++
Регистрация: 29.09.2006
Адрес: Казань
Цитата:
Сообщение от Sada Посмотреть сообщение
это сумма по нескольким записям
странно, а я думал, что это обращение к полю данной таблицы???
Старый 16.11.2006, 16:46   #3  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от Eldar9x Посмотреть сообщение
странно, а я думал, что это обращение к полю данной таблицы???
Eldar9x, мне примерно понятно ваше недоумение. Я сам через это проходил.
Недоумение возникает из-за того, что глядя на конструкцию:

select sum(amount) from payTrans where...

человек, знакомый с "нормальным" SQL (и пока не очень знакомый с "аксаптовским"), понимает, что "нормальный" SQL предъявит в качестве результата такого запроса "сумму поля amount из таблицы payTrans по тем записям, которые отбираются условием where...". Причем в контексте конкретной процедуры (метода) возникает естественный вопрос: "А где же оператор присваивания? Чему это полученное значение присваивается?"

На "аксаптовском SQL", а точнее на X++, вышеупомянутая конструкция означает, что "результат запроса на нормальном SQL" будет помещен в поле amount табличной переменной payTrans.
Т.е. на некотором псевдокоде можно записать примерно так:

payTrans.amount = (select sum(amount) from RPayTrans where ... )

Это просто нужно немножко переварить и прочувствовать (рюмка хорошего коньяка будет нелишней!).
За это сообщение автора поблагодарили: Eldar9x (1).
Старый 16.11.2006, 16:54   #4  
Eldar9x is offline
Eldar9x
MCTS
Аватар для Eldar9x
Oracle
MCBMSS
 
1,064 / 166 (8) ++++++
Регистрация: 29.09.2006
Адрес: Казань
Вот вот, мне тоже вначале хотелось увидеть что нибудь типа
blablabla = (select sum(amount) from RPayTrans where ... ),
где blablabla, какая то переменная...
Старый 16.11.2006, 18:48   #5  
glibs is offline
glibs
Member
Сотрудники компании It Box
Most Valuable Professional
Лучший по профессии 2011
Лучший по профессии 2009
 
4,942 / 911 (40) +++++++
Регистрация: 10.06.2002
Адрес: I am from Kyiv, Ukraine. Now I am in Moscow. For private contacts: glibs@hotmail.com
Цитата:
Сообщение от Gustav
...
select sum(amount) from payTrans where...

человек, знакомый с "нормальным" SQL
...
Хм... по-моему, в T-SQL при работе с курсором конструкция примерно такая же. Вы объявляете некий запрос в качестве курсора (он может содержать и агрегатные функции), а потом перебираете его строки. При этом вы тоже не работаете с конкретной записью.
__________________
С уважением,
glibs®
Старый 16.11.2006, 19:47   #6  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от glibs Посмотреть сообщение
Хм... по-моему, в T-SQL при работе с курсором конструкция примерно такая же. Вы объявляете некий запрос в качестве курсора (он может содержать и агрегатные функции), а потом перебираете его строки. При этом вы тоже не работаете с конкретной записью.
Нуу, речь, скорее, идет не о том, что "не с конкретной записью", а о сомнительной наглядности синтаксисе конструкции... Авторы самого X++ уж больно всё лаконично попытались описать. И эта лаконичность, увы, часто не льет воду не мельницу понимания, а скорее наоборот выходит некоторым боком (во завернул!)

Вот, не мудрствуя, скопировал из хелпа по T-SQL кусочек примера с курсором:
Код:
DECLARE @au_id varchar(11), @au_fname varchar(20), @au_lname varchar(40)
 
DECLARE authors_cursor CURSOR FOR 
SELECT au_id, au_fname, au_lname
FROM authors
WHERE state = "UT"
ORDER BY au_id
 
OPEN authors_cursor
 
FETCH NEXT FROM authors_cursor 
INTO @au_id, @au_fname, @au_lname
если читать это как бы на естественном языке, то получается примерно следующее:
Код:
ОБЪЯВЛЯЕМ наши_переменные
 
ОБЪЯВЛЯЕМ наш_курсор КАК КУРСОР ДЛЯ
SELECT... (причем SELECT - на нормальном SQL!)
 
ОТКРЫВАЕМ наш_курсор
 
СЧИТЫВАЕМ ОЧЕРЕДНУЮ (запись) ИЗ наш_курсор
В наши_переменные
Акцентирую внимание на последнем: СЧИТЫВАЕМ запись ИЗ наш_курсор В наши_переменные. ИЗ - В, ИЗ - В.

А здесь что? select sum(amount) from payTrans - ВЫБИРАЕМ СУММУ(amount) ИЗ... ВЫБИРАЕМ - ИЗ, ВЫБИРАЕМ - ИЗ. Ну, ИЗ-то выбираем, а ВО ЧТО выбираем-то? Вот и возникают непонятки. По-моему, вполне обоснованные.

У меня знакомство с подобного рода "проблемой" началось со встречи с примерно таким фрагментом:

select count(RecId) from RAssetTable

Уже к тому времени зная ответственно-почётную миссию идентификатора RecId во всей системе, мозг упорно отказывался понимать, что в этом фрагменте RecId является как бы не "самим собой", а содержит всего-навсего количество записей в конкретной таблице. Согласитесь, для "неокрепшего мозга", это немного башне-сносящая откровенность. "Мы понимаем, что мы чего-то не понимаем..."
Старый 17.11.2006, 09:49   #7  
Deep Dreamer is offline
Deep Dreamer
Участник
 
76 / 25 (1) +++
Регистрация: 05.03.2004
Адрес: Москва
Странно, но имея довольно богатый опыт работы с T-SQL у меня лично не возникло проблем в "догонянии" что делает select count(RecId) from RAssetTable
Не помню, чтобы заморачивался.
Просто если вы в T-SQL пишете
PHP код:
select count(recidfrom bmssa.LEDGERJOURNALTRANS 
то получите некий набор данных. Поскольку dataset будет содержать заказаный набор данных - т.е. что написано между select и from то и получите, особенно если переименоввывать колонки. Это очень гибко с одной стороны, но это слабо формализуемо с точки зрения embedded SQL языка X++...
Вот потому, наверное, и сделано так - чтобы не делать "виртуальных" динамически создающихся dataset'ов...
Хотя, конечно, мне, как разработчику, жутко не хватает конструкций типа такой:
PHP код:
select JOURNALNAMEAPPROVEDBY from dbo.LEDGERJOURNALTABLE as LJT
join 
(select JOURNALNUMcount(recid) as cnt from dbo.LEDGERJOURNALTRANS group by JOURNALNUM) as tmp
on tmp
.cnt and LJT.JOURNALNUM tmp.JOURNALNUM 
Имеется в виду нехватает вложенных select'ов, особенно с аггрегатными поименованными полями
Но, тем не менее, embedded SQL и табличные переменные X++ RULEZzz!
Старый 17.11.2006, 12:22   #8  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
небольшой офф-топик про WITH
Цитата:
Сообщение от Deep Dreamer Посмотреть сообщение
Имеется в виду нехватает вложенных select'ов, особенно с аггрегатными поименованными полями
Не хватает явно! Увы, много чего не хватает...

Хлебнув чуть больше года назад в Oracle 9.2 SQL-счастье под названием "фраза WITH с подзапросом" (subquery factoring clause), я уже с трудом понимаю, как можно возвращаться в такой каменный век SQL, где этого нет. Чесслово, говорю это не пижонства или красного словца ради. Несмотря на то, что синтаксис ANSI-шный, Microsoft, к сожалению, вроде не торопится прикручивать эту фичу к SQL Server (или может сделали уже?!) А вот обладатели Oracle 9.2 и выше, кто еще не в курсе, рекомендую обратить на этот WITH пристальное внимание.

В качестве примера привожу один свой рабочий запрос. Этот запрос выбирает неамортизируемые карточки основных средств в некоторой модели учета ОС ('GAAP') на определенную дату. Вникать в его бизнес-суть абсолютно необязательно. Это просто иллюстрация того, как подзапросы могут взаимодействовать между собой и как можно эффективно структурировать сложные запросы (практически в этаком "последовательно-процедурном" стиле, невиданном доселе для SELECT'ов):
Код:
SELECT * FROM
(
WITH    -- ЗДЕСЬ Я ОПРЕДЕЛЯЮ НЕСКОЛЬКО ИМЕНОВАННЫХ ПОДЗАПРОСОВ (имена "подчеркнуты")
 ------------------ 
 RATrans AS
 ------------------ 
  (SELECT 
   accountnum,
   MIN(CASE WHEN assettranstype = 3 THEN transdate END) acq_transdate,
   SUM(CASE WHEN assettranstype = 0 THEN amountmst ELSE 0 END) amt_0,
   SUM(CASE WHEN assettranstype = 2 THEN amountmst ELSE 0 END) amt_2,
   SUM(CASE WHEN assettranstype = 3 THEN amountmst ELSE 0 END) amt_3,
   SUM(CASE WHEN assettranstype = 4 THEN amountmst ELSE 0 END) amt_4,
   SUM(CASE WHEN assettranstype = 5 THEN amountmst ELSE 0 END) amt_5,
   SUM(CASE WHEN assettranstype = 7 THEN amountmst ELSE 0 END) amt_7,
   SUM(CASE WHEN assettranstype = 15 THEN amountmst ELSE 0 END) amt_15,
   SUM(CASE WHEN assettranstype = 16 THEN amountmst ELSE 0 END) amt_16,
   SUM(CASE WHEN assettranstype NOT IN (0,2,3,4,5,7,15,16) THEN amountmst ELSE 0 END) amt_other
  FROM RASSETTRANS 
  WHERE assetstandardid = 'GAAP'
   AND transdate  <= TO_DATE('30.09.2006', 'DD.MM.YYYY') 
  GROUP BY accountnum
  ),
 ------------------------
 HavingAmort AS
 ------------------------
  (SELECT accountnum 
  FROM RASSETTRANS 
  WHERE assettranstype = 0 
   AND assetstandardid = 'GAAP' 
   AND transdate <= TO_DATE('30.09.2006', 'DD.MM.YYYY')
  ),
 ----------------------------
 NoHavingAmort AS
 ----------------------------
  (SELECT ratable.accountnum AS accountnum
  FROM 
  RASSETTABLE ratable,
  HavingAmort ratrans -- <-- ИСПОЛЬЗУЕМ РАНЕЕ (выше) ОПРЕДЕЛЕННЫЙ ПОДЗАПРОС HavingAmort "как простую таблицу" - неплохо, правда? :-)
  WHERE ratable.accountnum = ratrans.accountnum(+)
   AND ratrans.accountnum IS NULL
  ),
 -------------------------------
 NecessaryAssets AS
 -------------------------------
  -- карточки, не имеющие амортизации в западном учете  (когда либо до даты)
  (SELECT accountnum FROM NoHavingAmort -- -- ОПЯТЬ ИСПОЛЬЗУЕМ РАНЕЕ (выше) ОПРЕДЕЛЕННЫЙ ПОДЗАПРОС NoHavingAmort "как простую таблицу", который в свою очередь - см. выше тоже включает подзапрос HavingAmort, т.е. уже пошла вложенность, сносящая башню при неиспользовании фразы WITH :-)
  UNION
  -- карточки, у которых нет амортизации (отключена)
  SELECT assetid FROM RASSETSTANDARDS WHERE depreciation = 0 AND assetstandardid = 'GAAP'
  UNION
  -- карточки, имеющие ост. стоимость <= 0, но не выбывшие ----------------------------------------------
  SELECT accountnum FROM
  (
   SELECT
   accountnum,
   (amt_2 + amt_3 + amt_4 + amt_16) AS PS,
   -(amt_0) AS Amort
   FROM RATrans  
   WHERE ROUND(amt_5,2) = 0 AND ROUND(amt_7,2) = 0
  ) 
  WHERE ROUND(PS,2) <= ROUND(Amort,2)
  )
--
-- СОБСТВЕННО НАЧИНАЕТСЯ ОСНОВНОЙ СЕЛЕКТ (самый внешний "SELECT * FROM ( WITH ...)" основным не считаем - это обертка для TOAD )
SELECT
 ratable.accountnum AS "Asset Code",
 ratable.dataareaid AS "Company",
 ratable.status AS "Status Value", 
 en.en_label AS "Status Label", 
 stand.depreciation AS "Depr Turn ON",
 neverb4.never_b4 AS "Never Before",
-- 
 CASE WHEN ratable.status <> 7 
  THEN NVL((trans.amt_2 + trans.amt_3 + trans.amt_4 + trans.amt_16), 0) 
  ELSE NVL((trans.amt_2 + trans.amt_3 + trans.amt_4 + trans.amt_16), 0) + NVL(stand.acquisitionprice, 0) 
  END AS "IC",
--
 -NVL(trans.amt_0, 0) AS "Depr",
--
 CASE WHEN ratable.status <> 7 
  THEN NVL((trans.amt_2 + trans.amt_3 + trans.amt_4 + trans.amt_16)+ (trans.amt_0), 0) 
  ELSE NVL((trans.amt_2 + trans.amt_3 + trans.amt_4 + trans.amt_16)+ (trans.amt_0), 0) + NVL(stand.acquisitionprice, 0) 
  END AS "Net",
--
 trans. acq_transdate AS "Acq.Date (GAAP, RATrans)",
 ratable.acquisitiondate AS "Acq.Date (RATable)",
 ratable.acquisitionprice AS "Acq.Price (RATable)",
 stand.acquisitionprice AS "Acq.Price (RAStand)",
 trans.amt_0 AS "Amt_0_Depreciation", 
 trans.amt_2 AS "Amt_2_Revaluation", 
 trans.amt_3 AS "Amt_3_Acquisition", 
 trans.amt_4 AS "Amt_4_AcquisitionAdj", 
 trans.amt_5 AS "Amt_5_DisposalSale", 
 trans.amt_7 AS "Amt_7_Disposal", 
 trans.amt_15 AS "Amt_15_Investment", 
 trans.amt_16 AS "Amt_16_InvestmentOpen", 
 amt_other AS "Amt_Other_AssetTransTypes"
-- 
FROM
-- 
 RATrans trans, -- <-- ИСПОЛЬЗУЕМ ИМЕННОВАННЫЙ ПОДЗАПРОС из зоны WITH
-- 
 (SELECT assetid, acquisitionprice, depreciation 
 FROM RASSETSTANDARDS 
 WHERE assetstandardid = 'GAAP'
 ) stand,
-- 
 -- ДЛЯ ИНДИКАЦИИ: карточки, не имеющие амортизации в западном учете  (когда либо до даты)
 (SELECT accountnum, 'Never' AS never_b4 
 FROM NoHavingAmort -- <-- ИСПОЛЬЗУЕМ ИМЕННОВАННЫЙ ПОДЗАПРОС из зоны WITH
 ) neverb4, 
-- 
 -- расшифровка значений статуса 
 (SELECT * FROM AX_BASE_ENUMS WHERE en_type = 'RAssetStatus') en, 
-- 
 (SELECT accountnum, dataareaid, status, acquisitiondate, acquisitionprice 
 FROM RASSETTABLE 
 ) ratable,
-- 
 NecessaryAssets nassets -- <-- ИСПОЛЬЗУЕМ ИМЕННОВАННЫЙ ПОДЗАПРОС из зоны WITH
-- 
WHERE nassets.accountnum = ratable.accountnum -- здесь без (+) !!!
 AND ratable.status = en.en_value(+)
 AND ratable.accountnum = neverb4.accountnum(+)
 AND ratable.accountnum = stand.assetid(+)  
 AND ratable.accountnum = trans.accountnum(+)
)
ORDER BY 1
Запрос можно попробовать запустить в вашей системе, заменив модель учета 'GAAP' на какую-нибудь модель учета ОС из вашей системы. Также необходимо закомментировать фрагменты, ссылающиеся на мою специфическую таблицу AX_BASE_ENUMS. Ну, или предварительно создать ее в схеме вашей Аксапты (наполнять данными не обязательно - RassetTable вяжется на нее левым джойном):
Код:
CREATE TABLE AX_BASE_ENUMS
(
  EN_TYPE     VARCHAR2(100 BYTE)                NOT NULL,
  EN_VALUE    NUMBER(10)                        NOT NULL,
  EN_LABEL    VARCHAR2(200 BYTE)                NOT NULL,
  EN_ELEMENT  VARCHAR2(100 BYTE)
)
Старый 16.11.2006, 16:19   #9  
eugene egorov is offline
eugene egorov
Участник
Аватар для eugene egorov
 
273 / 97 (4) ++++
Регистрация: 05.06.2002
Адрес: Москва
Please note, that the results will always be returned in the table variable. If you use a field list in the select statement, only those fields will be available in the table variable. If you use aggregate functions such as sum or count, the sums or counts are returned in the fields you perform the sum or count over. This also means that you cannot count average or sum date-fields as the result is not a date.
__________________
любитель портвейна и снов с прокисшей капустой в усах
За это сообщение автора поблагодарили: RVS (1), Eldar9x (1).
Старый 16.11.2006, 16:26   #10  
RVS is offline
RVS
Сенбернар
Аватар для RVS
Злыдни
 
696 / 130 (6) +++++
Регистрация: 27.02.2003
Адрес: Королев МО
Переведу : Eldar9x, в Вашем случае - это НИКАКАЯ запись. Это ПЕРЕМЕННАЯ типа "запись таблицы" payTrans, ЕДИНСТВЕННОЕ поле которой имеет осмысленное значение. В этом поле сидит СУММА, которую Вы заказывали.

Вот.

ЗЫ : Опять CAPS LOCK заедать начал
__________________
Best Regards,
Roman
За это сообщение автора поблагодарили: Eldar9x (1).
Теги
amount, запрос (query), как правильно

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
SUM по Amount в Query. С динамическими фильтрами по Grid Poleax DAX: Программирование 8 25.09.2008 16:04
Разница NotInTTS и Found Logger DAX: База знаний и проекты 6 18.09.2008 12:35
Отчет "Запасы в наличии" evb DAX: Программирование 19 17.01.2008 07:37
Вопрос про Demand Planner slava09 DAX: Функционал 4 25.09.2006 11:43
select sum(amount) from временная таблица ATimTim DAX: Программирование 6 11.06.2004 14:16
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 13:40.