|
![]() |
#1 |
Программатор
|
|
|
![]() |
#2 |
MCTS
|
|
|
![]() |
#3 |
Moderator
|
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). |
![]() |
#4 |
MCTS
|
Вот вот, мне тоже вначале хотелось увидеть что нибудь типа
blablabla = (select sum(amount) from RPayTrans where ... ), где blablabla, какая то переменная... ![]() |
|
![]() |
#5 |
Member
|
Цитата:
Сообщение от Gustav
...
select sum(amount) from payTrans where... человек, знакомый с "нормальным" SQL ...
__________________
С уважением, glibs® |
|
![]() |
#6 |
Moderator
|
Цитата:
Вот, не мудрствуя, скопировал из хелпа по 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 является как бы не "самим собой", а содержит всего-навсего количество записей в конкретной таблице. Согласитесь, для "неокрепшего мозга", это немного башне-сносящая откровенность. "Мы понимаем, что мы чего-то не понимаем..." ![]() |
|
![]() |
#7 |
Участник
|
Странно, но имея довольно богатый опыт работы с T-SQL у меня лично не возникло проблем в "догонянии" что делает select count(RecId) from RAssetTable
Не помню, чтобы заморачивался. Просто если вы в T-SQL пишете PHP код:
Вот потому, наверное, и сделано так - чтобы не делать "виртуальных" динамически создающихся dataset'ов... Хотя, конечно, мне, как разработчику, жутко не хватает конструкций типа такой: PHP код:
Но, тем не менее, embedded SQL и табличные переменные X++ RULEZzz! ![]() |
|
![]() |
#8 |
Moderator
|
небольшой офф-топик про WITH
Цитата:
![]() Хлебнув чуть больше года назад в 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 Код: 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) ) |
|
![]() |
#9 |
Участник
|
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). |
![]() |
#10 |
Сенбернар
|
Переведу : Eldar9x, в Вашем случае - это НИКАКАЯ запись. Это ПЕРЕМЕННАЯ типа "запись таблицы" payTrans, ЕДИНСТВЕННОЕ поле которой имеет осмысленное значение. В этом поле сидит СУММА, которую Вы заказывали.
Вот. ЗЫ : Опять CAPS LOCK заедать начал ![]()
__________________
Best Regards, Roman |
|
|
За это сообщение автора поблагодарили: Eldar9x (1). |
Теги |
amount, запрос (query), как правильно |
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|