AXForum  
Zurück   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Kennwort vergessen?
Registrieren Forum Rules Hilfe Benutzerliste Heutige Beiträge Suchen

 
 
Themen-Optionen Thema durchsuchen Ansicht
Alt 08.09.2005, 12:04   #1  
6apcyk ist offline
6apcyk
Участник
 
57 / 11 (1) +
Registriert seit: 17.08.2005
Помогите с query
Есть таблица1, таблица2, таблица3. У которых есть общее поле itemId(у таблиц таблица2 и таблица3 может дублироваться).

Надо получить query такое что в нем будут только те записи, для которых itemId есть в третей или во второй таблице.
Alt 08.09.2005, 12:51   #2  
Bega ist offline
Bega
Участник
Benutzerbild von Bega
 
382 / 444 (15) +++++++
Registriert seit: 18.08.2005
Ort: Москва
что вроде этого пойдет ?:
Query q;
QueryBuildDataSource qbr, qbr2, qbr3;
;
qbr = q.addDataSource(tablenum(Table1));
qbr2 = qbr.addDataSource(tablenum(Table2));
qbr2.addLink(tablenum(Table1, ItemId), tablenum(Table2, ItemId));
qbr2.joinMode(JOINMODE::ExistsJoin);
qbr3 = qbr.addDataSource(tablenum(Table3));
qbr3.addLink(tablenum(Table1, ItemId), tablenum(Table3, ItemId));
qbr3.joinMode(JOINMODE::ExistsJoin);
Alt 08.09.2005, 12:58   #3  
6apcyk ist offline
6apcyk
Участник
 
57 / 11 (1) +
Registriert seit: 17.08.2005
так я тоже пробовал
Этот запрос join-ит по пересечению таблиц 2 и 3
так что не подходит
Alt 08.09.2005, 13:00   #4  
AndyD ist offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2.560 / 2494 (89) +++++++++
Registriert seit: 20.08.2005
2 Bega

Неа. Не правильно. На сервер пойдут отдельные запросы для каждой таблицы

2 барсук

PHP-Code:
Query Q = new Query();
;
    
Q.addDataSource(tablenum(Table1));
    
Q.dataSourceTable(tablenum(Table1)).addDataSource(tablenum(Table2));
    
Q.dataSourceTable(tablenum(Table2)).joinMode(JoinMode::ExistsJoin);
    
Q.dataSourceTable(tablenum(Table2)).addLink(fieldnum(table1ItemId), fieldnum(table2ItemId));

    
Q.dataSourceTable(tablenum(Table2)).addDataSource(tablenum(Table3));
    
Q.dataSourceTable(tablenum(Table3)).joinMode(JoinMode::InnerJoin);
    
Q.dataSourceTable(tablenum(Table3)).addLink(fieldnum(table2ItemId), fieldnum(table3ItemId)); 
PS. Хотя и без ExistsJoin можно все и на InnerJoin сделать
__________________
Axapta v.3.0 sp5 kr2
Alt 08.09.2005, 13:32   #5  
6apcyk ist offline
6apcyk
Участник
 
57 / 11 (1) +
Registriert seit: 17.08.2005
2 AndyD
вопрос как в этот запрос оставляет в таблице 1, те записи из таблицы 3 которых нет в таблице 2?
Alt 08.09.2005, 13:45   #6  
ahtoh
Гость
 
n/a
Zitat:
Изначально опубликовано 6apcyk
2 AndyD
вопрос как в этот запрос оставляет в таблице 1, те записи из таблицы 3 которых нет в таблице 2?
никак, потому что он неправильный
Alt 08.09.2005, 13:46   #7  
ahtoh
Гость
 
n/a
можете добавить в базу знаний: 2 экзист джойна эквивалентны экзист + иннер джойну
Alt 08.09.2005, 14:05   #8  
Bega ist offline
Bega
Участник
Benutzerbild von Bega
 
382 / 444 (15) +++++++
Registriert seit: 18.08.2005
Ort: Москва
На чистом SQL это выглядело бы так:

select Table1.*
from Table1
left join Table2 on Table2.ItemId = Table1.ItemId
left join Table3 on Table3.ItemId = Table1.ItemId
where not Table2.ItemId is null or not Table3.ItemId is null
--либо
select Table1.*
from Table1
where
exists(select * from Table2 where Table2.ItemId = Table1.ItemId)
or
exists(select * from Table3 where Table3.ItemId = Table1.ItemId)

В одном Query такое наверное не сделаешь.
Alt 08.09.2005, 14:11   #9  
ahtoh
Гость
 
n/a
единственное решение, которое приходит на ум - создать вьюшку из table2 и table3 и полями соотв itemid2, itemid3 и в запросе писать table1.itemid == view.itemid2 || table1.itemid == view.itemid3
Alt 08.09.2005, 14:17   #10  
AndyD ist offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2.560 / 2494 (89) +++++++++
Registriert seit: 20.08.2005
Извиняюсь, неправильно прочитал условия.

Я предлагал для выбора по "И"
__________________
Axapta v.3.0 sp5 kr2
Alt 08.09.2005, 14:47   #11  
Владимир Максимов ist offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1.719 / 1204 (44) ++++++++
Registriert seit: 13.01.2004
Blog-Einträge: 3
Мне кажется, что сделать это через Query - не получится.

Дело в том, что Query собирает все условия через AND. Вписать OR получается далеко не всегда. Обычно для этого приходится сильно "извращаться".

Стандартное решение - это делать Query по первой таблице, а внутри перебора полученных записей (while (QueryRun.next())) проверять факт вхождения во вторую или третью.

"НЕ стандартное" - это формировать запрос напрямую на сервере через объект Connection.
Alt 08.09.2005, 15:04   #12  
AndyD ist offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2.560 / 2494 (89) +++++++++
Registriert seit: 20.08.2005
Если вопрос в том, чтобы пробежать по Query и получить значения, то это можно реализовать. Но мне кажется, что данном случае речь идет о визуализации. 2 6apcyk?
__________________
Axapta v.3.0 sp5 kr2
Alt 08.09.2005, 16:07   #13  
ahtoh
Гость
 
n/a
Zitat:
Изначально опубликовано Владимир Максимов
Мне кажется, что сделать это через Query - не получится.
я выше написал, как это можно сделать
Alt 08.09.2005, 16:16   #14  
Владимир Максимов ist offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1.719 / 1204 (44) ++++++++
Registriert seit: 13.01.2004
Blog-Einträge: 3
Zitat:
Изначально опубликовано ahtoh
я выше написал, как это можно сделать
Так ведь не через Query! Точнее, не чистый Query.

Причем не совсем ясно, как предполагается делать вьюшку. Ведь в этом случае нужно объединение по FULL JOIN. Иначе условие OR не получиться. Я не в курсе, можно такое во вьюшке сделать?
Alt 08.09.2005, 16:43   #15  
ahtoh
Гость
 
n/a
что значит не query
а full join сделать проще некуда - relations не указываешь да и все

попробуй на досуге выполнить select ledgertrans join ledgertrans2 поймешь, что джойн тут cамый, что ни на есть ФУЛЛ
Alt 08.09.2005, 17:10   #16  
AndyD ist offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2.560 / 2494 (89) +++++++++
Registriert seit: 20.08.2005
Получите декартово произведение, т.е. каждая запись из таблицы1 будет объединяться с каждой записью из таблицы2. В результате кол-во записей во view будет count(таблица1) * count(таблица2)
__________________
Axapta v.3.0 sp5 kr2
Alt 08.09.2005, 17:20   #17  
Владимир Максимов ist offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1.719 / 1204 (44) ++++++++
Registriert seit: 13.01.2004
Blog-Einträge: 3
Zitat:
Изначально опубликовано AndyD
Получите декартово произведение, т.е. каждая запись из таблицы1 будет объединяться с каждой записью из таблицы2. В результате кол-во записей во view будет count(таблица1) * count(таблица2)
В данном случае - это не принципиально.

Основная цель - это получить во View полный набор значений ItemId, как из второй, так и из первой таблицы (объединение значений). Это можно сделать через UNION, FULL JOIN или через декартово произведение. Суть не измениться. Хотя, конечно, при декартовом произведении записей будет больше всего.

Дальше уже надо смотреть, что получиться быстрее - такая вьюха или перебор в цикле.
Alt 08.09.2005, 17:46   #18  
AndyD ist offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2.560 / 2494 (89) +++++++++
Registriert seit: 20.08.2005
Зачем перебор в цикле?

PHP-Code:
table1      tbl;
query       q = new Query();
QueryRun    qr;
;

Q.addDataSource(tablenum(Table1));
Q.dataSourceTable(tablenum(Table1)).addDataSource(tablenum(Table2));
Q.dataSourceTable(tablenum(Table2)).joinMode(JoinMode::InnerJoin);
Q.dataSourceTable(tablenum(Table2)).addLink(fieldnum(table1ItemId), fieldnum(table2ItemId));

Q.addDataSource(tablenum(Table1));

Q.dataSourceTable(tablenum(Table1), 2).addDataSource(tablenum(Table3));
Q.dataSourceTable(tablenum(Table3)).joinMode(JoinMode::InnerJoin);
Q.dataSourceTable(tablenum(Table3)).addLink(fieldnum(table1ItemId), fieldnum(table3ItemId));

Q.dataSourceTable(tablenum(Table3)).addDataSource(tablenum(Table2));
Q.dataSourceTable(tablenum(Table2), 2).joinMode(JoinMode::NoExistsJoin);
Q.dataSourceTable(tablenum(Table2), 2).addLink(fieldnum(table3ItemId), fieldnum(table2ItemId));

qr = new QueryRun(q);
while (
qr.next())
{
    
tbl qr.getNo(1);
    if (!
tbltbl qr.getNo(3);
    
info(tbl.ItemId);

В принципе можно разбить на два отдельных запроса. Минусы - записи отсортированы сначала по table2.itemId, а затем по table3.itemId. И для просмотра неудобно.

По повод view - каким образом объединять ее с table1? Ведь в результате получим соответствующие увеличение кол-ва записей для датасорса.

Единственное верное решение в данном случае - использование UNION. Как грязный xак - можно подправить view на сервере
__________________
Axapta v.3.0 sp5 kr2
Alt 08.09.2005, 18:07   #19  
Владимир Максимов ist offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1.719 / 1204 (44) ++++++++
Registriert seit: 13.01.2004
Blog-Einträge: 3
Приведенный код не решает поставленную задачу. У тебя получилось примерно следующее:

( Table1.ItemId = Table2.ItemId )
Декартово произведение
(Table1.ItemId = Table3.ItemId AND Table3.ItemId NOT EXISTS(Table2.ItemId))

Вся проблема именно в том, что объединение пойдет не по типу UNION (что предполагается), а именно как декартово произведение. Представляешь количество "мусора"?

А то, что предлагает ahtoh это примерно следующее:

Table1.ItemId EXISTS((Table2.ItemId) декартово произведение (Table3.ItemId))

Поскольку составить такой Query не получится, то он предлагает то, что внутри Exists оформить как отдельный View.

Все корректно. Вопрос только в скорости такой выборки.
Alt 08.09.2005, 20:02   #20  
AndyD ist offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2.560 / 2494 (89) +++++++++
Registriert seit: 20.08.2005
Нет, там по другому. На сервер пойдет два запроса результаты которых будут объеденены на клиенте. Обратите внимание table1 там добавляется два раза. Т.е получится следующее

datasource1(table1) - datasource3(table1)
--------------------------------------
table1.itemid = table2.itemId - пусто
table1.itemid = table2.itemId - пусто
table1.itemid = table2.itemId - пусто
пусто - table1.itemid = table3.itemId
пусто - table1.itemid = table3.itemId
пусто - table1.itemid = table3.itemId

По поводу view я уже и сам понял, просто не учел про ExistsJoin
Тут есть замечание - необходимо не Table1.ItemId Exists(), а Table1.Itemid IN. Как его задать - не предствляю себе.

Если задавать ExistsJoin, то получается
PHP-Code:
    Q.addDataSource(tablenum(Table1), "t1");
    
Q.dataSourceTable(tablenum(Table1)).addDataSource(tablenum(View1), "v1");
    
Q.dataSourceTable(tablenum(View1)).joinMode(JoinMode::ExistsJoin);
    
Q.dataSourceTable(tablenum(View1)).addRange(fieldnum(view1itemid1)).value("((v1.itemId1 == t1.itemId) || (v1.itemId2 == t1.itemId))"); 
Но тут, как не раз было замечено, встает вопрос производительности
__________________
Axapta v.3.0 sp5 kr2
 

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Dynamics AX: QueryRun and Query Objects - Binding operation failed to allocate buffer space Blog bot DAX Blogs 0 03.04.2009 08:05
palleagermark: Sample union query from AX 2009 Blog bot DAX Blogs 0 11.07.2008 20:05
Dynamics AX Geek: Using query() Blog bot DAX Blogs 0 28.10.2006 16:40
Помогите новичку в создании Query lev DAX: Программирование 2 19.06.2006 10:29
Проблема с составлением Query axaLearner DAX: Программирование 10 01.12.2005 15:00

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Gehe zu

Рейтинг@Mail.ru
Alle Zeitangaben in WEZ +3. Es ist jetzt 06:21 Uhr.
Powered by vBulletin® Version 3.8.5 (Deutsch)
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.