Регистрация  |  Вход

Кверим лист записей с "индивидуальными" условиями у каждой

Сложно это объяснить, но вот пример.

я хочу получить запись где (Создатель = Я и ДатаСоздания между Сегодня и Сегодня.addDays(-1)).
нет проблем.

и теперь следующую:
я хочу получить запись где (Создатель = "ilya leshchuk" и ДатаСоздания между 12мая и 12мая.addDays(-1)).

т.е. в каждом новом случае требуется получить запис(и) с уникальной комбинацией значений условий

например, запись с комбинацией параметров (Создатель = Я и ДатаСоздания между 12мая и 12мая.addDays(-1)) мне не нужна.

так, вот как выкверить эти записи одним махом по таким "индивидуальным" условиям без "лишних" записей?

Сложно это объяснить, но вот пример.

я хочу получить запись где (Создатель = Я и ДатаСоздания между Сегодня и Сегодня.addDays(-1)).
нет проблем.

и теперь следующую:
я хочу получить запись где (Создатель = "ilya leshchuk" и ДатаСоздания между 12мая и 12мая.addDays(-1)).

т.е. в каждом новом случае требуется получить запис(и) с уникальной [b]комбинацией значений[/b] условий

например, запись с комбинацией параметров (Создатель = Я и ДатаСоздания между 12мая и 12мая.addDays(-1)) мне не нужна.

так, вот как выкверить эти записи одним махом по таким "индивидуальным" условиям без "лишних" записей?

Ничего не понял... дай пару конкретных Select

[SELECT Id FROM Contact WHERE OwnerId=:userinfo.getUserId() AND CreatedDate>StartDate AND CreatedDate<EndDate]

Пока не вижу никаких проблем, ставь овнера какого хочешь...

Ничего не понял... дай пару конкретных Select

[code]
[SELECT Id FROM Contact WHERE OwnerId=:userinfo.getUserId() AND CreatedDate>StartDate AND CreatedDate<EndDate]
[/code]

Пока не вижу никаких проблем, ставь овнера какого хочешь...

wilder
[SELECT Id FROM Contact WHERE OwnerId=:userinfo.getUserId() AND CreatedDate>StartDate AND CreatedDate<EndDate]

и далее мне нужна такая выборка

[SELECT Id FROM Contact WHERE OwnerId=:другойЮзер AND CreatedDate>ДругаяStartDate AND CreatedDate<ДругаяEndDate]

вопрос как выкверить их вместе, совместить эти квери так, чтобы не было записей с "комбинированными" значениями условий, а именно так получится, если кверить через OwnerId IN :listOfIds AND CreatedDate IN :listOfDates и так далее

[quote="wilder"][code][SELECT Id FROM Contact WHERE OwnerId=:userinfo.getUserId() AND CreatedDate>StartDate AND CreatedDate<EndDate][/code][/quote]

и далее мне нужна такая выборка
[code][SELECT Id FROM Contact WHERE OwnerId=:другойЮзер AND CreatedDate>ДругаяStartDate AND CreatedDate<ДругаяEndDate][/code]

вопрос как выкверить их вместе, совместить эти квери так, чтобы не было записей с "комбинированными" значениями условий, а именно так получится, если кверить через OwnerId [b]IN[/b] :listOfIds AND CreatedDate [b]IN[/b] :listOfDates и так далее

Вообще нифига не понял замысел, но в чем проблема сделать 2 квери, вместо одного и потом разбирать данные из одного результата. лимит SOQL хоть и есть, но все равно запас существует. Наделай сколько тебе угодно этимх Query и гоняй (пофиг на производительность)

Вообще нифига не понял замысел, но в чем проблема сделать 2 квери, вместо одного и потом разбирать данные из одного результата. лимит SOQL хоть и есть, но все равно запас существует. Наделай сколько тебе угодно этимх Query и гоняй (пофиг на производительность)

мне нужны транспортные средства типа = машина и оборудование = колеса
и еще мне нужны транспортные средства типа = самолет и оборудование = крылья
и таких - сотни комбинаций

я могу сделать одно общее квери через тип IN всеНужныеВарианты AND оборудование IN всеПодходящиеВарианты

но тогда кроме всех прочих я получу транспортные средства типа = машина и оборудование = крылья, а такие мне не нужны, я конечно могу их позже выфильтровать в коде, но может это можно сразу решить на уровне квери

мне нужны транспортные средства  типа = машина и оборудование = колеса
и еще мне  нужны транспортные средства  типа = самолет и оборудование = крылья
и таких - сотни комбинаций

я могу сделать одно общее квери через тип IN всеНужныеВарианты AND оборудование IN всеПодходящиеВарианты

но тогда кроме всех прочих я получу транспортные средства  типа = машина и оборудование = крылья, а такие мне не нужны, я конечно могу их позже выфильтровать в коде, но может это можно сразу решить на уровне квери

Den Brown
но тогда кроме всех прочих я получу транспортные средства типа = машина и оборудование = крылья

А разве у тебя в базе будут такие записи?
Другое дело что если тебе надо достать машины розовые и самолеты синие - то тогда логично.

Не думаю что средства SOQL позволят это сделать - как вариант пожешь подготовить псевдо индеск - поле специальное и туда складывать комбинации полей которые собираешься искать. И уже делать выборку чисто по этому полю, например

SELECT ... FROM ... WHERE SuperIndex__c IN ('машиназеленая', 'самолетрозовый')

[quote="Den Brown"]но тогда кроме всех прочих я получу транспортные средства типа = машина и оборудование = крылья[/quote]
А разве у тебя в базе будут такие записи?
Другое дело что если тебе надо достать машины розовые и самолеты синие - то тогда логично.

Не думаю что средства SOQL позволят это сделать - как вариант пожешь подготовить псевдо индеск - поле специальное и туда складывать комбинации полей которые собираешься искать. И уже делать выборку чисто по этому полю, например

SELECT ... FROM ... WHERE SuperIndex__c IN ('машиназеленая', 'самолетрозовый')

ну, понятно, что машин с крыльями не будет.

речь идет о комбинации значений в полях CreatedById and CreatedDate

но ты предложил вполне рабочий и действенный вариант.

(почему то у меня где-то в памяти всплывает, что где-то я читал, что системные поля CreatedById and CreatedDate на самом деле одно объединенное поле... бред какой-то... с чем-то другим путаю...)

ну, понятно, что машин с крыльями не будет.

речь идет о комбинации значений в полях CreatedById and CreatedDate

но ты предложил вполне рабочий и действенный вариант.

(почему то у меня где-то в памяти всплывает, что где-то я читал, что системные поля CreatedById and CreatedDate на самом деле одно объединенное поле... бред какой-то... с чем-то другим путаю...)

А в чем проблема просто использовать OR?

А в чем проблема просто использовать OR?

Gres
Цитировать
А в чем проблема просто использовать OR?

Ну это уже динамический запрос получается если в общем виде и может быть достаточно длинный. А так да можно юзать.

[quote="Gres"]Цитировать
А в чем проблема просто использовать OR?[/quote]

Ну это уже динамический запрос получается если в общем виде и может быть достаточно длинный. А так да можно юзать.

Gres
А в чем проблема просто использовать OR?

да, а почему бы не так? будет запрос с действительно "индивидуальными" условиями.

но, как заметили, какая максимальная длина запроса, который можно скормить БД?

у меня может быть 600 комбинаций-условий...

[quote="Gres"]А в чем проблема просто использовать OR?[/quote]

да, а почему бы не так? будет запрос с действительно "индивидуальными" условиями.

но, как заметили, какая максимальная длина запроса, который можно скормить БД?

у меня может быть 600 комбинаций-условий...

Den Brown
у меня может быть 600 комбинаций-условий...

Мне кажется цикл - наше все :)

[quote="Den Brown"]

у меня может быть 600 комбинаций-условий...[/quote]

Мне кажется цикл - наше все :)

wilder
Мне кажется цикл - наше все :)

я не верю, что ты хочешь сказать, что нужно сделать 600 SOQL запросов через цикл...

но то что 600 комбинаций можно в цикле аккуратно собрать в один длинный ( AND ) OR ( AND ) OR... стринг это понятно, не понятно, сможет ли БД проглотить запрос такой длинны...

[quote="wilder"]Мне кажется цикл - наше все :)[/quote]

я не верю, что ты хочешь сказать, что нужно сделать 600 SOQL запросов через цикл...

но то что 600 комбинаций можно в цикле аккуратно собрать в один длинный (  AND ) OR ( AND ) OR... стринг это понятно, не понятно, сможет ли БД проглотить запрос такой длинны...

Что-то Den мне кажется что вы перемудрили с бизнес логикой.
Я понимаю это еще могут быть задачки для собеседования - как составить мега запрос, но лучше на реальном проекте это дело упростить. Или если совсем никак - то работать с промежуточными таблицами.

Что-то Den мне кажется что вы перемудрили с бизнес логикой. 
Я понимаю это еще могут быть задачки для собеседования - как составить мега запрос, но лучше на реальном проекте это дело упростить. Или если совсем никак - то работать с промежуточными таблицами. 

Dmitry Shnyrev
Что-то Den мне кажется что вы перемудрили с бизнес логикой.

по факту я сейчас выбираю в квери все "самолеты и машины" , а потом уже в коде, в цикле (в вложенном цикле, что особенно меня смущает) один за одним проверяю все правильные комбиниции на наличие таковых в полученном листе записей. Вот я и хотел упростить этот момент, изначально выкверив только нужные записи

но пока и так работает...

[quote="Dmitry Shnyrev"]Что-то Den мне кажется что вы перемудрили с бизнес логикой. [/quote]

по факту я сейчас выбираю в квери все "самолеты и машины" , а потом уже в коде, в цикле (в вложенном цикле, что особенно меня смущает) один за одним проверяю все правильные комбиниции на наличие таковых в полученном листе записей. Вот я и хотел упростить этот момент, изначально выкверив только нужные записи

но пока и так работает...

Делается селект в котором через in передается массив возможных элементов. А уже потом в цикле проверяется насколько запись соответствует параметрам.

Делается селект в котором через in передается массив возможных элементов. А уже потом в цикле проверяется насколько запись соответствует параметрам.

wilder
Делается селект в котором через in передается массив возможных элементов. А уже потом в цикле проверяется насколько запись соответствует параметрам.

так все и есть. просто дальше там получается цикл в цикле

вот сейчас сижу и вывожу логику вложенного цикла в заранее создаваемую Мапу, чтоб не было таких ужасов

[quote="wilder"]Делается селект в котором через in передается массив возможных элементов. А уже потом в цикле проверяется насколько запись соответствует параметрам.[/quote]

так все и есть. просто дальше там получается цикл в цикле

вот сейчас сижу и вывожу логику вложенного цикла в заранее создаваемую Мапу, чтоб не было таких ужасов

Den Brown
в заранее

не понял зачем там цикл в цикле

map<id,Datetime[]> initialContitions = new map<id,Datetime[]>();
//Заполняешь необходимыми данными, где Id - OwnerId
DateTime[] startLst = new DateTime[]{};
DateTime[] endLst = new DateTime[]{};

for (DateTime[] Item : initialContitions.values()) {
startLst.add(Item[0]);
endLst.add(Item[1]);
}

Contact[] cLst = [select id from contact where ownerId In :initialContitions.keyset() and CreatedDate IN :startLst AND CreatedDate IN :endLst];

for (Contact Item : cLst) {
DateTime[] dItem = initialContitions.get(Item.OwnerId);
if (!(Item.CreatedDate>=dItem[0] && Item.CreatedDate<=dItem[1])) continue;
твоя логика
}

Ясное дело, должны быть проверки на null. Но сути это не меняет.

[quote="Den Brown"]в заранее[/quote]
не понял зачем там цикл в цикле

[code]map<id,Datetime[]> initialContitions = new map<id,Datetime[]>();
//Заполняешь необходимыми данными, где Id - OwnerId
DateTime[] startLst = new DateTime[]{};
DateTime[] endLst = new DateTime[]{};

for (DateTime[] Item : initialContitions.values()) {
    startLst.add(Item[0]);
    endLst.add(Item[1]);
}

Contact[] cLst = [select id from contact where ownerId In :initialContitions.keyset() and CreatedDate IN :startLst AND CreatedDate IN :endLst];

for (Contact Item : cLst) {
    DateTime[] dItem = initialContitions.get(Item.OwnerId);
    if (!(Item.CreatedDate>=dItem[0] && Item.CreatedDate<=dItem[1])) continue;
    твоя логика
}[/code]

Ясное дело, должны быть проверки на null. Но сути это не меняет.

Den Brown
вот сейчас сижу и вывожу логику вложенного цикла в заранее создаваемую Мапу, чтоб не было таких ужасов

МАПЫ наше ВСЕ! Срочно берись за их использование и все for только в один уровень.

Я когда постиг дзен Map<> то просто прыгнул выше головы в программировании. Теперь у меня редко когда без мап обходится дело. Многие коллеги кстати раньше жаловались что мозг сломать можно об мой код - зато оптимизация офигенная!

[quote="Den Brown"]вот сейчас сижу и вывожу логику вложенного цикла в заранее создаваемую Мапу, чтоб не было таких ужасов[/quote]
МАПЫ наше ВСЕ! Срочно берись за их использование и все for только в один уровень.

Я когда постиг дзен Map<> то просто прыгнул выше головы в программировании. Теперь у меня редко когда без мап обходится дело. Многие коллеги кстати раньше жаловались что мозг сломать можно об мой код :D - зато оптимизация офигенная! :D 

Смысл крайне просто - перед основным циклом подготавливаешь данные - расскладываешь по мапам таким образом чтобы в основном цикле все сводилось к паре строчек .get из мапы плюс пара if.
Многие коллеги - гуру ООП для этого используют не знаю как правильно называется по ООПешному - вложенные классы вместо мап - да это улучшает читабельность - но я жутко ленивые и не люблю отдельно под каждый вариант представления данных объявлять класс.

Смысл крайне просто - перед основным циклом подготавливаешь данные - расскладываешь по мапам таким образом чтобы в основном цикле все сводилось к паре строчек .get из мапы плюс пара if.
Многие коллеги - гуру ООП для этого используют не знаю как правильно называется по ООПешному - вложенные классы вместо мап - да это улучшает читабельность - но я жутко ленивые и не люблю отдельно под каждый вариант представления данных объявлять класс.

Dmitry Shnyrev
МАПЫ наше ВСЕ

он CaseSensetive так что с пониманием их нужно использовать

[quote="Dmitry Shnyrev"]МАПЫ наше ВСЕ[/quote]

он CaseSensetive так что с пониманием их нужно использовать

Dmitry Shnyrev
МАПЫ наше ВСЕ! Срочно берись за их использование и все for только в один уровень.

это совершенно верно.

wilder, ты все правильно написал, особенно мне нравится continue в цикле: сразу видно - интеллигентный человек писал.

и спасибо всем за участие, я уже думал забросить оптимизацию данного кода, но чувствую, что вы "не дадите спокойно умереть"...

ладно давайте разберем как убрать вложенный цикл в данном случае.
дело в том, что у нас там нет надежного уникального ключа для сопоставления двух записей (как вы помните из соседней темы, у нас есть имя Юзера, но никак не его АйДи). Более того, во внутреннем цикле мы ищем не одну запись, а несколько (их может быть несколько или ни одной).

задача такая:
использую выборку записей loginAsCommunityUser за последний месяц по имени LoginAs юзеров (АйДи у нас нет) найти в объекте Изменения те записи, которые были сделано теми же юзерами в период с момента создания конкретной loginAsCommunityUser записи до конца того дня. Таким образом мы можем относительно определить какие изменения могли были быть сделаны после того loginAsCommunityUser логина (но не знаем кто именно их сделал: реальный комьюнити юзер или ЛогинЭс юзер плюс у разных юзеров могут быть одно и тоже имя, но пока это опускаем).

также не будем пока разбирать как мы кверим объекты,
и вот у нас есть два списка:

один loginAsCommunityUser с именем Юзера и датой создания

второй с записями Изменения, тоже с именем Юзера и датой создания

сначала запускается цикл перебора loginAsCommunityUser
внутри него запускается перебор записей Изменения
и если имя юзера на обоих записей совпадает и дата создания записи Изменения в пределах момента создания записи loginAsCommunityUser и конца того дня - то мы забираем такую запись в новый список.

пока я додумался частично редуцировать вложенный цикл:

вначале создать Мапу записей Изменения, где ключом является имя юзера, а значением является Лист записей Изменения с этим юзером.

в таком случае внутри внешнего цикла loginAsCommunityUser я дергаю из этой Мапы по имени юзера только нужные записи Изменения, и перебираю во вложенном цикле только их (осталось проверить только их даты), что значительно сокращает количество итераций внутреннего цикла.

еще спасибо за участие в обсуждение

[quote="Dmitry Shnyrev"]МАПЫ наше ВСЕ! Срочно берись за их использование и все for только в один уровень.[/quote]

это совершенно верно.

wilder, ты все правильно написал, особенно мне нравится continue в цикле: сразу видно - интеллигентный человек писал.

и спасибо всем за участие, я уже думал забросить оптимизацию данного кода, но чувствую, что вы "не дадите спокойно умереть"...

ладно давайте разберем как убрать вложенный цикл в данном случае.
дело в том, что у нас там нет надежного уникального ключа для сопоставления двух записей (как вы помните из соседней темы, у нас есть имя Юзера, но никак не его АйДи). Более того, во внутреннем цикле мы ищем не одну запись, а несколько (их может быть несколько или ни одной).

задача такая:
использую выборку записей loginAsCommunityUser за последний месяц по имени LoginAs юзеров (АйДи у нас нет) найти в объекте Изменения те записи, которые были сделано теми же юзерами в период с момента создания конкретной loginAsCommunityUser записи  до конца того дня. Таким образом мы можем относительно определить какие изменения могли были быть сделаны после того loginAsCommunityUser логина (но не знаем кто именно их сделал: реальный комьюнити юзер или ЛогинЭс юзер плюс у разных юзеров могут быть одно и тоже имя, но пока это опускаем).

также не будем пока разбирать как мы кверим объекты, 
и вот у нас есть два списка: 

один loginAsCommunityUser с именем Юзера и датой создания

второй с записями Изменения, тоже с именем Юзера и датой создания

сначала запускается цикл перебора loginAsCommunityUser
внутри него запускается  перебор записей Изменения 
и если имя юзера на обоих записей совпадает и дата создания записи Изменения в пределах момента создания записи loginAsCommunityUser и конца того дня - то мы забираем такую запись в новый список.

пока я додумался частично редуцировать вложенный цикл:

вначале создать Мапу записей Изменения, где ключом является имя юзера, а значением является Лист записей Изменения с этим юзером.

в таком случае внутри внешнего цикла loginAsCommunityUser я дергаю из этой Мапы по имени юзера только нужные записи Изменения, и перебираю во вложенном цикле только их (осталось  проверить только их даты), что значительно сокращает количество итераций внутреннего цикла.

еще спасибо за участие в обсуждение