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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 16.11.2006, 18:48   #21  
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   #22  
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   #23  
Deep Dreamer is offline
Deep Dreamer
Участник
 
76 / 24 (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, 10:13   #24  
Eldar9x is offline
Eldar9x
MCTS
Аватар для Eldar9x
Oracle
MCBMSS
 
1,064 / 166 (8) ++++++
Регистрация: 29.09.2006
Адрес: Казань
а если я хочу после этой конструкции обратиться не к полученной переменной, которая содержит подсчитанную сумму, а к полю записи этой таблицы (т.е. к обычному текущему курсору), тогда интересно что делать? Ведь если я пишу
RPayTrans.Amount, то это выдаст ту самую сумму по записям, с другой стороны, мне нужно обратиться к конкретной записи по полю, т.е. RPayTrans.Amount - как тогда быть?
Старый 17.11.2006, 10:21   #25  
KiselevSA is offline
KiselevSA
Злыдни
Аватар для KiselevSA
Злыдни
Лучший по профессии 2015
 
958 / 333 (13) ++++++
Регистрация: 25.01.2002
Адрес: Москва
Сделать выборку записи, т.е. select без агрегирования
За это сообщение автора поблагодарили: Eldar9x (1).
Старый 17.11.2006, 10:22   #26  
Sada is offline
Sada
Программатор
Аватар для Sada
 
1,450 / 153 (8) ++++++
Регистрация: 29.03.2005
Адрес: Толи Барнаул, толи Москва
Цитата:
Сообщение от KiselevSA Посмотреть сообщение
Сделать выборку записи, т.е. select без агрегирования
Например, во второй табличной переменной, чтоб сумма осталося
За это сообщение автора поблагодарили: Eldar9x (1).
Старый 17.11.2006, 10:28   #27  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Eldar9x, рекомендую еще обратить внимание на мою тему Прикольная конструкция: оператор select с полем (она также внизу болтается в "Похожих темах" к этой теме). Думаю, Вам понравится.
Старый 17.11.2006, 12:22   #28  
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)
)
Старый 31.01.2007, 19:07   #29  
SerAl is offline
SerAl
Участник
 
163 / 44 (2) +++
Регистрация: 24.06.2004
Адрес: г. Москва
Добрый вечер!

У меня есть название поля в таблице считай "amount", т.е :
fieldId = fieldName2Id(tableNum(RPayTrans), "amount");
RPayTrans.(fieldId);

Как мне к нему обратится, в конструкции "Select sum() from"?
Старый 01.02.2007, 14:03   #30  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Регистрация: 21.10.2004
Можно так:
X++:
Query q = new Query('');
QueryBuildDatSource ds;
;
ds = q.addDataSource(TableNum(RPayTrans));
ds.addSelectiontField(fieldName2Id(tableNum(RPayTrans), "amount"), SelectionField::Sum);
Старый 01.02.2007, 15:41   #31  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от Lucky13 Посмотреть сообщение
Можно так:
X++:
Query q = new Query('');
А зачем пустую строку передавать?
Старый 01.02.2007, 16:10   #32  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Регистрация: 21.10.2004
Трудно сказать. Правильнее наверное было бы не передавать. То ли в предыдущих версиях аксапты этот параметр был обязательным, то ли у предыдущего программиста были свои сообращения на этот счет. Но факт остается фактом - данная конструкция благодаря буферу обмена расплодилась по всему коду приложения.
Старый 01.02.2007, 16:20   #33  
Recoilme is offline
Recoilme
злыдень
Аватар для Recoilme
Злыдни
 
895 / 192 (8) ++++++
Регистрация: 18.06.2003
Цитата:
Сообщение от Gustav Посмотреть сообщение
Не хватает явно! Увы, много чего не хватает...
УжОс! Многа букв.
И слава богу что нет.. Я одного не понимаю чем этот изврат, которого нет, лучше хранимок и триггеров которые везде есть уже n десятков лет ???
Неужели программировать в родном "последовательно-процедурном" стиле не приятнее на порядок???
Вот как выглядит типичная обработка на firebird, по моему все понятно без слов:
Код:
AS
declare variable znak integer;
declare variable sumnds double precision;
BEGIN
  IF (NEW.ID IS NULL) THEN
    NEW.ID = GEN_ID(GEN_Z_PROVODKA_ID,1);
  /* Перед подстановкой в основную считаем параметры осн записи и рассчитаем себестоимость*/

  if (new.id_pribyl<>0) then /* Прибыли */
  begin
        select first 1 data, skladkod, statuskod, celkod from Z_PRIBYL
        where Z_PRIBYL.id = NEW.id_pribyl into new.data, new.skladprihod, new.status, new.typeoper;
        select result from f_valuta_calc(new.summaval,new.data,new.valutakod) into new.summaprihod;
        new.summaoper = new.summaprihod;
  end

  if (new.id_ubytok<>0) then/* Убытки */
  begin
        select first 1 data, skladkod, statuskod, celkod from Z_UBYTOK
        where Z_UBYTOK.id = NEW.id_ubytok into new.data, new.skladrashod, new.status, new.typeoper;
        select result from z_ostatok_stoim(new.status,new.tovarkod,new.skladrashod,new.kolnov * (-1)) into new.summarashod;
        new.summaoper = new.summarashod;
  end

  if (new.id_perem <> 0) then /*Перемещения*/
  begin
    select first 1 dataprih, datarash, skladrashodkod, skladprihodkod, statuskod, celkod from Z_PEREM
    where Z_PEREM.id = new.id_perem into new.data,new.datarashod, new.skladrashod, new.skladprihod, new.status, new.typeoper;
    select result from z_ostatok_stoim(new.status,new.tovarkod,new.skladrashod,new.kolnov * (-1)) into new.summarashod;
    new.summaprihod = (-1)*new.summarashod;
    new.summaoper = new.summarashod;
  end

  if (new.id_zpnakl <> 0) then /* Закупка */
  begin
        select first 1 data, skladkod, statuskod, celkod, postkod, valutakod from zp_nakl
        where zp_nakl.id = NEW.id_zpnakl into new.data, new.skladprihod, new.status, new.typeoper, new.postkod, new.valutakod;
        select result from f_valuta_calc((new.summaval-new.summands),new.data,new.valutakod) into new.summaprihod;
        UPDATE ZP_NAKL SET SUMMA = SUMMA + new.summaprihod WHERE (ID = new.id_zpnakl);
        select result from f_valuta_calc(new.summands,new.data,new.valutakod) into new.summaoper;
        UPDATE ZP_NAKL SET SUMMANDS = SUMMANDS + new.summaoper WHERE (ID = new.id_zpnakl);
        new.summaoper = new.summaprihod;
  end

  if (new.id_prnakl <> 0) then /* Продажа */
  begin
        select first 1 data, skladkod, statuskod, celkod, klientkod, valutakod from pr_nakl
        where pr_nakl.id = NEW.id_prnakl into new.data, new.skladrashod, new.status, new.typeoper, new.klientkod, new.valutakod;
        select result from f_valuta_calc(new.summaval-new.summands,new.data,new.valutakod) into new.summaoper;
        select result from z_ostatok_stoim(new.status,new.tovarkod,new.skladrashod,new.kolnov * (-1)) into new.summarashod;
        select result from f_valuta_calc(new.summands,new.data,new.valutakod) into sumnds;
        UPDATE PR_NAKL SET
            SUMMA = SUMMA + new.summaoper,
            SUMMANDS = SUMMANDS + :sumnds
        WHERE (ID = new.id_prnakl);
  end
  if (new.kolnov = 0) then exit;
  /* Контроль */
  if ((new.tovarkod is null) or (new.skladprihod is null AND new.skladrashod is null))  then
    execute procedure ERROR('Проводки в никуда быть не может');
  /* Собственно тригер */
  /* Приход:"+", Расход:"-" */
  if (new.status > 0) then znak = 1; else znak = (-1); /*Возвраты*/
  if (not (new.skladprihod is null)) then
  begin
    new.kolprihod = new.kolnov;
    execute procedure z_ostatok_calc (new.tovarkod,new.skladprihod,new.kolprihod,new.summaprihod,:znak,new.status);
  end
  if (not (new.skladrashod is null)) then
  begin
    new.kolrashod = new.kolnov*(-1);
    execute procedure z_ostatok_calc (new.tovarkod,new.skladrashod,new.kolrashod,new.summarashod,:znak,new.status);
  end
  /* Обновим статусы*/
  if (new.status = 1) then new.ZAAVKA = new.kolnov;
  else
    if (new.status = 2) then new.ZAKAZ = new.kolnov;
    else
        if (new.status = 3) then new.REZERV = new.kolnov;
        else
            if (new.status = 4) then new.PUT = new.kolnov;
            else
                if (new.status = 5) then new.ZAVER6ENO = new.kolnov;

END
__________________
Ибо зло есть лучшая сила человека. "Человек должен становиться все лучше и злее" -- так учу я. /Ф. Ницше/
Старый 01.02.2007, 16:41   #34  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
А еще CTE (они, кстати, появились в MS SQL 2005) можно определять рекурсивно:
Код:
WITH DirectReports(ManagerID, EmployeeID, EmployeeLevel) AS 
(
    SELECT ManagerID, EmployeeID, 0 AS EmployeeLevel
    FROM HumanResources.Employee
    WHERE ManagerID IS NULL
    UNION ALL
    SELECT e.ManagerID, e.EmployeeID, EmployeeLevel + 1
    FROM HumanResources.Employee e
        INNER JOIN DirectReports d
        ON e.ManagerID = d.EmployeeID 
)
SELECT ManagerID, EmployeeID, EmployeeLevel 
FROM DirectReports ;

Последний раз редактировалось belugin; 01.02.2007 в 16:43.
Теги
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, время: 19:46.