Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Горячая тема (более 10 ответов) Отбор значений в индексированной тз (число прочтений - 4428 )
RuporAbsurda
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 413
Зарегистрирован: 29. Июня 2006
Отбор значений в индексированной тз
18. Июля 2011 :: 12:59
Печать  
Возможно ли в индексированной тз сделать отбор по нескольким значениям, например в колонке есть
знач1
знач2
знач1
знач3
Возможно ли сделать отбор сразу и по знач1 и по знач3, чтобы в выборке было
знач1
знач1
знач3
  
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Отбор значений в индексированной тз
Ответ #1 - 18. Июля 2011 :: 14:09
Печать  
Скорее всего, возможно: пересечением или соединением.
  

De quelle planète es-tu?
Наверх
 
IP записан
 
Sergio
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 21
Зарегистрирован: 19. Июля 2011
Re: Отбор значений в индексированной тз
Ответ #2 - 19. Июля 2011 :: 22:09
Печать  
RuporAbsurda писал(а) 18. Июля 2011 :: 12:59:
Возможно ли в индексированной тз сделать отбор по нескольким значениям, например в колонке есть
знач1
знач2
знач1
знач3
Возможно ли сделать отбор сразу и по знач1 и по знач3, чтобы в выборке было
знач1
знач1
знач3


В твоем случае сработает инверсия:
ИТ.ДобавитьИндекс("Значение","Значение");
ИТ.УстановитьФильтр("знач2","знач2","Значение",,1);
  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Отбор значений в индексированной тз
Ответ #3 - 20. Июля 2011 :: 06:26
Печать  
Sergio писал(а) 19. Июля 2011 :: 22:09:
В твоем случае сработает инверсия:
ИТ.ДобавитьИндекс("Значение","Значение");
ИТ.УстановитьФильтр("знач2","знач2","Значение",,1);


Я так понимаю, в исходной заде отсуствие знач4 не гарантируется.
  
Наверх
 
IP записан
 
Sergio
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 21
Зарегистрирован: 19. Июля 2011
Re: Отбор значений в индексированной тз
Ответ #4 - 21. Июля 2011 :: 21:39
Печать  
Satans Claws писал(а) 20. Июля 2011 :: 06:26:
Sergio писал(а) 19. Июля 2011 :: 22:09:
В твоем случае сработает инверсия:
ИТ.ДобавитьИндекс("Значение","Значение");
ИТ.УстановитьФильтр("знач2","знач2","Значение",,1);


Я так понимаю, в исходной заде отсуствие знач4 не гарантируется.


Как ни странно, сегодня у меня самого возникла та же задача.
Нашел пять методов решения:
1. Искомые значения - в АссоциативныйВектор. В ИТ - добавить колонку, заполнить по алгоритму неточным поиском, отфильтровать по 1.
2. Искомые значения - в АссоциативныйВектор. В ИТ - добавить колонку, заполнить по алгоритму точным поиском, отфильтровать инверсией по -1.
3. Искомые значения - в СписокЗначений. В ИТ - добавить колонку, заполнить по алгоритму неточным поиском, отфильтровать по 1.
4. Искомые значения - в СписокЗначений. В ИТ - добавить колонку, заполнить по алгоритму точным поиском, отфильтровать инверсией по 0.
5. Отфильтровать по циклу искомые значения и объединить.

Для решения, что же лучше, пришлось написать небольшую обработку. Вывод: 5-й метод - лучше по скорости и не требует создания дополнительной колонки.
  

Test_003.ert ( 23 KB | Загрузки )
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Отбор значений в индексированной тз
Ответ #5 - 22. Июля 2011 :: 15:30
Печать  
Я добавил предложенные вначале методы решения "Пересечение" и "ВнутреннееСоединение".
В целом, интересные результаты.
Показательно, что в зависимости от набора данных, используемого для фильтрации, алгоритмы масштабируются совершенно по-разному.


Очередной пример воплощения принципа дырявых абстракций.
fez тут был бы доволен, если бы он не был доволен там. Улыбка


Отличный тест, Sergio.
  

Test_003_001.ert ( 30 KB | Загрузки )

De quelle planète es-tu?
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Отбор значений в индексированной тз
Ответ #6 - 22. Июля 2011 :: 16:06
Печать  
Затраты на Пересечение
ORD_5603 == ?RemoveAt@CDWordArray@@QAEXHH@Z
  

conjunction.JPG ( 131 KB | Загрузки )
conjunction.JPG

De quelle planète es-tu?
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Отбор значений в индексированной тз
Ответ #7 - 22. Июля 2011 :: 16:06
Печать  
Затраты на Соединение 100000, 50%
  

join.JPG ( 103 KB | Загрузки )
join.JPG

De quelle planète es-tu?
Наверх
 
IP записан
 
Sergio
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 21
Зарегистрирован: 19. Июля 2011
Re: Отбор значений в индексированной тз
Ответ #8 - 23. Июля 2011 :: 17:08
Печать  
Sergio писал(а) 21. Июля 2011 :: 21:39:
Вывод: 5-й метод - лучше по скорости и не требует создания дополнительной колонки.


Вынужден признать, что вывод про 5-метод - ошибочный. Он напрямую зависит от количества значений, которые надо отфильтровать. И если их столько же, например, сколько значений в искомой таблице, результат зашкалит (это просто огромное количество циклов)!!!
Удаление строк (в методах, предложенных kms), сильно замедляет процесс. Результат для меня, по крайней мере, - неожиданный. Учту на будущее при применении ИТ.
Нашел еще один метод, сочетающий преимущества методов kms и фильтрации по доп.колонке. Все - в обработке.

Еще подумалось, что возможна какая-то зависимость скорости удаления строк от того, откуда происходит удаление: все удаляемые строки находятся в начале таблицы, все - в конце или разбросаны хаотично по искомой таблице. Результат - в обработке.
« Последняя редакция: 24. Июля 2011 :: 13:43 - Sergio »  

Test_003_002.ert ( 26 KB | Загрузки )
Наверх
 
IP записан
 
Sergio
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 21
Зарегистрирован: 19. Июля 2011
Re: Отбор значений в индексированной тз
Ответ #9 - 24. Июля 2011 :: 05:14
Печать  
RuporAbsurda писал(а) 18. Июля 2011 :: 12:59:
Возможно ли в индексированной тз сделать отбор по нескольким значениям, например в колонке есть
знач1
знач2
знач1
знач3
Возможно ли сделать отбор сразу и по знач1 и по знач3, чтобы в выборке было
знач1
знач1
знач3



Могу предложить результат исследований методов решения твоей задачи:

Функция ИТ_ОтфильтроватьПоСпискуЗначений(Таблица, КолонкаТаблицы, _СписокЗначений)
     РезультТаблица = СоздатьОбъект("ИндексированнаяТаблица");

     Если ТипЗначенияСтр(_СписокЗначений) <> "СписокЗначений" Тогда
           Возврат РезультТаблица;
     КонецЕсли;

// ++++++++++++++++ kms (c)
     _ТЗ = СоздатьОбъект("ТаблицаЗначений");
     _СписокЗначений.Выгрузить(_ТЗ);

     ТаблицаВектор = СоздатьОбъект("ИндексированнаяТаблица");
     ТаблицаВектор.Загрузить(_ТЗ);
     ТаблицаВектор.ПереименоватьКолонку("_1", КолонкаТаблицы);
     ТаблицаВектор.НоваяКолонка("ДопЗначение");
     ТаблицаВектор.ЗаполнитьКолонку(, "ДопЗначение", 1);
     ИндексТаблицыВектора = ТаблицаВектор.ДобавитьИндекс(КолонкаТаблицы, КолонкаТаблицы);
// ---------------- kms (c)

     Таблица.ЛевоеСоединение(КолонкаТаблицы, ТаблицаВектор, ИндексТаблицыВектора, "ДопЗначение");
     Таблица.ДобавитьИндекс("ДопЗначение", "ДопЗначение");
     Таблица.УстановитьФильтр(1, 1, "ДопЗначение");
     Таблица.Выгрузить(РезультТаблица, "ДопЗначение");
     Таблица.ВыключитьФильтр("ДопЗначение");
     Таблица.УдалитьИндекс("ДопЗначение");
     Таблица.УдалитьКолонку("ДопЗначение");

     Возврат РезультТаблица;
КонецФункции

На вид - тяжеловато, но работает на любых размерах исходной таблицы адекватно ИТ.Пересечение() и заметно быстрее.
Точку пока еще ставить рано...
  
Наверх
 
IP записан
 
Sergio
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 21
Зарегистрирован: 19. Июля 2011
Re: Отбор значений в индексированной тз
Ответ #10 - 24. Июля 2011 :: 06:56
Печать  
Вот так переработанная функция сжует и "АссоциативныйВектор", и "СписокЗначений", и "ТаблицаЗначений", и "ИндексированнаяТаблица", и строку с разделителями (";", ",") на входе.

Функция _Пересечение(Таблица, КолонкаТаблицы, Знач _Список) Экспорт
     РезультТаблица = СоздатьОбъект("ИндексированнаяТаблица");
     _ИсхСписок = _Список;
     _ПереименоватьКолонку = 0;

     Если ТипЗначенияСтр(_ИсхСписок) = "Строка" Тогда
           _СЗ = СоздатьОбъект("СписокЗначений"); // если есть своя функция преобразования СтрокаСРазделителями => СписокЗначений - применить ее
           _СЗ.ИзСтрокиСРазделителями("""" + СтрЗаменить(_ИсхСписок, ?(Найти(_ИсхСписок, ";") > 0, ";", ","), """,""") + """");
           _ИсхСписок = _СЗ;
     КонецЕсли;

     Если ТипЗначенияСтр(_ИсхСписок) = "АссоциативныйВектор" Тогда
           _СЗ = СоздатьОбъект("СписокЗначений"); // если есть своя функция преобразования АссоциативныйВектор => СписокЗначений - применить ее
           _ИсхСписок.Выгрузить(_СЗ);
           _ИсхСписок = _СЗ;
     КонецЕсли;

     Если ТипЗначенияСтр(_ИсхСписок) = "СписокЗначений" Тогда
           _ТЗ = СоздатьОбъект("ТаблицаЗначений"); // если есть своя функция преобразования СписокЗначений => ТаблицаЗначений - применить ее
           _ИсхСписок.Выгрузить(_ТЗ);
           _ИсхСписок = _ТЗ;
           _ПереименоватьКолонку = 1;
     КонецЕсли;

     Если ТипЗначенияСтр(_ИсхСписок) = "ТаблицаЗначений" Тогда
           _ИТ = СоздатьОбъект("ИндексированнаяТаблица"); // если есть своя функция преобразования ТаблицаЗначений => ИндексированнаяТаблица - применить ее
           _ИТ.Загрузить(_ИсхСписок);
           Если _ПереименоватьКолонку = 1 Тогда
                 _ИТ.ПереименоватьКолонку("_1", КолонкаТаблицы);
           КонецЕсли;
           _ИсхСписок = _ИТ;
     КонецЕсли;

     Если ТипЗначенияСтр(_ИсхСписок) <> "ИндексированнаяТаблица" Тогда
           Возврат РезультТаблица;
     КонецЕсли;

     _ИсхСписок.НоваяКолонка("ДопЗначение");
     _ИсхСписок.ЗаполнитьКолонку(, "ДопЗначение", 1);
     ИндексИсхТаблицы = _ИсхСписок.ДобавитьИндекс(КолонкаТаблицы, КолонкаТаблицы);

     Таблица.ЛевоеСоединение(КолонкаТаблицы, _ИсхСписок, ИндексИсхТаблицы, "ДопЗначение");
     Таблица.ДобавитьИндекс("ДопЗначение", "ДопЗначение");
     Таблица.УстановитьФильтр(1, 1, "ДопЗначение");
     Таблица.Выгрузить(РезультТаблица, "ДопЗначение");
     Таблица.ВыключитьФильтр("ДопЗначение");
     Таблица.УдалитьИндекс("ДопЗначение");
     Таблица.УдалитьКолонку("ДопЗначение");

     Возврат РезультТаблица;
КонецФункции

PS

RuporAbsurda. Помогло?
« Последняя редакция: 24. Июля 2011 :: 08:09 - Sergio »  
Наверх
 
IP записан
 
Sergio
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 21
Зарегистрирован: 19. Июля 2011
Re: Отбор значений в индексированной тз
Ответ #11 - 24. Июля 2011 :: 07:23
Печать  
В принципе я понял причину низкой скорости работы удаления строки в ИТ. А вот поняли ли ее вы, дорогие радиослушатели? Подсказка:
1. методы 3, 4, 5, 6, 8, 9, 10, 11, исследованные в моей обработке;
2. http://www.1cpp.ru/forum/YaBB.pl?num=1310993964/5#5, 3-я и 4-я строка;
3. http://www.1cpp.ru/forum/YaBB.pl?num=1310993964/6#6 и http://www.1cpp.ru/forum/YaBB.pl?num=1310993964/7#7 - картинки (спасибо kms)
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать