Публикация

ESQ select с несколькими exists на клиентской части

Добрый день коммьюнити,

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

Итак, у нас есть запрос с двумя where in или exists. В приведенном ниже примере он должен выбрать из перечня схем в SysSchema только те, UId которых есть в таблице SysModuleEntity в поле SysEntitySchemaUid и при этом сами значения SysModuleEntity должны быть в таблице SysModule и там признак IsSystem не должен быть false.

В переводе на русский: нам нужно отобрать только схемы, у которых есть пользовательские разделы, не являющиеся системными.

select * 
from sysschema 
where uid in (
    select sysentityschemauid from sysmoduleentity 
    where id in (
        select sysmoduleentityid from sysmodule
        where issystem = 'false'
    )
)

--он же, только через exists
select * 
from sysschema 
where exists (
    select id from sysmoduleentity 
    where sysentityschemauid = uid and exists(
        select id from sysmodule 
        where sysmoduleentityid = sysmoduleentity.id
        and issystem = 'false'
    )
)

Выполнить его нужно на клиентской части и по каким-то причинам нужно выполнить только через ESQ и лучше всего одним запросом. Например, мне это было нужно, чтобы вставить свой фильтр справочного поля в уже существующий экземпляр esq вместо того, чтобы городить тонны замещающей логики.
Чтобы это выполнить, нам нужно внимательно руководствоваться вот этой великолепной статьей https://community.terrasoft.ru/articles/kak-sdelat-filtraciu-pola-po-exists-filtru-s-parametrom-znacenie-drugogo-pola и проявить немного смекалочки) 
Сколько ни бейтесь у вас не выйдет сделать подобным образом:
 

esq.filters.addItem(Terrasoft.createExistsFilter("[SysModule:SysModuleEntity:SysEntitySchemaUId:UId].Id")

а жаль, было бы удобно)

Вместо этого нам нужно сделать сразу несколько вложенных фильтров, вот так:
 

var subSubFilters = Terrasoft.createFilterGroup();
subSubFilters.addItem(Terrasoft.createColumnFilterWithParameter(
    Terrasoft.ComparisonType.EQUAL,
    "IsSystem", false));
var subFilters = Terrasoft.createFilterGroup();
subFilters.addItem(Terrasoft.createExistsFilter("[SysModule:SysModuleEntity].Id", subSubFilters));
esq.filters.addItem(Terrasoft.createExistsFilter("[SysModuleEntity:SysEntitySchemaUId:UId].Id", subFilters));

Фух, работа сделана, можно наградить себя чем-то вкусным и лучше всего очень вредным :)

Поделиться

3 комментария

А почему бы вообще не вывернуть наизнанку, написав запрос к SysModule, связанным при помощи inner join с SysModuleEntity и затем с SysSchema?

select distinct sysschema.* from sysmodule 
inner join sysmoduleentity on sysmodule.sysmoduleentityid = sysmoduleentity.id
inner join sysschema on  sysmoduleentity.sysentityschemauid = sysschema.uid
where issystem  = 'false'

 

Зверев Александр,

выглядит интересно, но как это написать с помощью фильтра в esq?)

Как добавляются join разных типов, см. тут. А distinct включается в конструкторе ESQ при помощи isDistinct: true (через запятую после значения rootSchemaName).

Войдите или зарегистрируйтесь, чтобы комментировать