К списку форумов К списку тем
Регистрация    Правила    Главная форума    Поиск   
Имя: Пароль:
Рекомендовать в новости

1cpp NOT IN (SELECT

Гость
0 - 13.11.2012 - 15:23
Как наложить условие "кроме выбранной группы"

Если КромеНоменклатура = 0 Тогда
Если ВыбНоменклатура.ЭтоГруппа() = 1 Тогда
Рез = Рез + " AND $ДокС.Номенклатура IN (SELECT Val FROM #ВыбНоменклатура)";
RS.УложитьСписокОбъектов(ВыбНоменклатура, "#ВыбНоменклатура", "Номенклатура");
Иначе
Рез = Рез + " AND $ДокС.Номенклатура = :ВыбНоменклатура";
RS.УстановитьТекстовыйПараметр("ВыбНоменклатура",В ыбНоменклатура);
КонецЕсли
Иначе
Если ВыбНоменклатура.ЭтоГруппа() = 1 Тогда
Рез = Рез + " AND ($ДокС.Номенклатура NOT IN (SELECT Val FROM #ВыбНоменклатура))";
RS.УложитьСписокОбъектов(ВыбНоменклатура, "#ВыбНоменклатура", "Номенклатура");
Иначе
Рез = Рез + " AND ($ДокС.Номенклатура <> :ВыбНоменклатура)";
RS.УстановитьТекстовыйПараметр("ВыбНоменклатура",В ыбНоменклатура);
КонецЕсли;
КонецЕсли;

соответственно "IN (SELECT" работает как положенно, а при "NOT IN (SELECT" результат пустая таблица.



Гость
1 - 13.11.2012 - 16:43
Закинь элементы из ВыбНоменклатура в список значений и по нему условие делать.
Гость
2 - 14.11.2012 - 04:45
По моему в Рез = Рез + " AND ($ДокС.Номенклатура <> :ВыбНоменклатура" надо писать #ВыбНоменклатура, а не с двоеточиес
Гость
3 - 14.11.2012 - 06:58
NOT($ДокС.Номенклатура IN (SELECT Val FROM #ВыбНоменклатура))
Гость
4 - 14.11.2012 - 07:38
1 В списке значений не работает
2 :ВыбНоменклатура правильно. = :ВыбНоменклатура - работает, <> :ВыбНоменклатура - выдает пустой результат.
3 NOT($ДокС.Номенклатура IN (SELECT Val FROM #ВыбНоменклатура)) выдает пустой результат.

sql 2008
сам запрос
|SELECT Итоги.Статус as [Статус],
| Итоги.ДатаДок as ДатаДок,
| Итоги.Док as [Док $Документ]
| ,Итоги.ДатаДок3 as [ДатаДок3],
| Итоги.Док_вид as Док_вид,
| Итоги.ДокОснование as [ДокОснование $Документы]
|FROM (
|SELECT CASE WHEN Жур.IsMark = 1 THEN 7 ELSE CASE WHEN Жур.Closed & 1 = 1 THEN 2 ELSE 1 END END as Статус,
| Жур.Date_Time_IDDoc as Дата,
| CAST(LEFT(Жур.Date_Time_IDDoc, 8) as DateTime) as ДатаДок,
| Жур.IDDoc as Док,
| Жур.IDDocDef as Док_вид
| ,$ДокС.Номенклатура as Номенклатура,
| $Док.ДокОснование as ДокОснование,
| (SELECT CAST(LEFT(Жур2.Date_Time_IDDoc, 8) as DateTime) as ДатаДок2
| FROM _1SJourn as Жур2
| WHERE Жур2.IDDoc = RIGHT($Док.ДокОснование,9)) as ДатаДок3
|FROM $Документ.ВозвратОтПокупателя as Док (NOLOCK)
|INNER JOIN _1SJourn as Жур (NOLOCK) ON Жур.IDDoc = Док.IDDoc
|INNER JOIN $ДокументСтроки.ВозвратОтПокупателя as ДокС (NOLOCK) ON ДокС.IDDoc = Док.IDDoc
|WHERE Жур.Date_Time_IDDoc BETWEEN :ДатаНачала AND :ДатаКонца~ "+УсловиеЗапросаИ(RS)+УсловиеСтатусаДокумента( )+"
|) as Итоги
|WHERE Итоги.ДатаДок - Итоги.ДатаДок3 > "+КолвоДней+"
|ORDER BY Итоги.Дата

Может я что не доглядел?
5 - 14.11.2012 - 08:05
я не программист, но по моей логике операторы In и NotIn работают по булевой алгебре "Правда" <-> "Ложь"...

если Value пустое или NULL(?), то рассматриваемые операторы могут не сработать...

я почему так думаю?
чудес не бывает... когда работает f и не работает обратная f^(-1), то пустышка находится вне рассматриваемого интервала... в данном случае - вне выбранной группы...

если я не прав, то пусть старшие товарищи меня поправят (с) Топтыгин из к/ф "Ещё раз про любовь"
Гость
6 - 14.11.2012 - 08:21
Гена, вполне логично, тем более что это подтверждает практика. Просто не нашел правильного примера.
Конечно можно запихнуть "все кроме" в список, но что-то пихать под миллион значений туда не хочется.
Тем более для обычных запросов Условие (НЕ(ПеремЗапроса в ИмяЭлемента)) работае так же бысто (точнее так же медленно). Не подскажет форум с гуглом, придется идти к админу вылавливать во что преобразуется "Условие (НЕ(ПеремЗапроса в ИмяЭлемента))"
7 - 14.11.2012 - 08:28
для правильного примера достаточно запустить свой отчёт в другой короткой базе, например, в демо...

если там работает NotIn, то мы правильно поставили диагноз рабочей базе и тогда просто останется вычистить там гнилую пустышку в номенклатуре или в доке, тем более, что этот флюк может портить жизнь и в других ситуациях...
Гость
8 - 14.11.2012 - 09:26
(0)Покажи, что возвращает Запрос.Отладка(1)

и что в список пихаешь
ЗЫ: ВыбНоменклатура.Выбран() = ?
9 - 14.11.2012 - 10:04
В 1С++ не силён, но что делает
SELECT Val FROM #ВыбНоменклатура?
По идее, надо селектить элементы, у которых родитель не равен выбранной группе, но это верно для 1 уровня, т.е. в группе нет вложенной группы, иначе придётся искать все вложенные группы..
Гость
10 - 14.11.2012 - 10:35
(9) в #ВыбНоменклатура будут все элементы, принадлежащие выбранной группе на всех уровнях.. только и всего.


http://www.1cpp.ru/docum/icpp/html/O...#putobjectlist
11 - 14.11.2012 - 10:41
10 понятно.
Гость
12 - 14.11.2012 - 10:53
Прошу прощения. Ступил. Давно не смотрел, что выводит Запрос.Отладка(1).
Просто в условия попадали два взаимоисключающих события. Спасибо Ёпрст. Все работает. Иду стреляться. Потратил 5 часов из-за своей невнимательности.
Еще раз прошу прощения.
Гость
13 - 14.11.2012 - 15:30
все не осилил, но обычно пишу :
1 - IN ()
2 - NOT IN ()
Без всяких не равно. Равно или не равно писать нельзя, надо писать IN - принадлежность к выборке
Гость
14 - 14.11.2012 - 21:44
13 USSR
Если фильтр по одному элементу, то тоже IN
Можно обосновать или дать ссылку?
15 - 15.11.2012 - 08:11
14-vovan519 >без разницы: "=" или "IN".
Всё равно оптимизатор перведет IN в =.
Правда оптимизатор потратит на это ресурсы, но очень не значительные. :)
Гость
16 - 15.11.2012 - 09:44
15 Заинтересовало.
Провел эксперемент. время - разница из _GetPerformanceCounter()
Фильтр - один элемент справочника
Режим 0 - "=" и УстановитьТекстовыйПараметр
Режим 1 - IN и УложитьСписокОбъектов
В базе активно работаю, поэтому и разброс показателей, разные режимы запускались по очереди "0,1,0,1", поэтому погрешность разного рода кэштрования не велика. Вот результат.
Режим 0 1068
Режим 1 1241
Режим 0 865
Режим 1 1232
Режим 0 858
Режим 1 1361
Режим 0 1244
Режим 1 1542
Режим 0 1147
Режим 1 5059
Режим 0 1596
Режим 1 1351
Режим 0 869
Режим 1 1496
Режим 0 2091
Режим 1 1327
Режим 0 840
Режим 1 1480
Режим 0 1128
Режим 1 1377
Режим 0 833
Режим 1 1360
Режим 0 860
Режим 1 1397
Конечно 0,8 сек или 1,3 сек разницы нет, но все же.
17 - 15.11.2012 - 14:32
16-vovan519 >Некорректное сравнение.
Ты сравнивал не IN и = ,
а УстановитьТекстовыйПараметр и УложитьСписокОбъектов.
УстановитьТекстовыйПараметр просто подставляет патаметр в текст запроса, если грубо, то время тратится только на приведение параметра к типу строка и замене в тексте запроса самого параметра на его строковое представление.
УложитьСписокОбъектов - формирует таблицу на сервере и заполняет её переданными данными, а затем сервер, при выполнении запроса произодит join с этой таблицей. Естественно эта операция стоит гораздо дороже.

Я думаю, USSR имел ввиду несколько другое.
Либо val IN (:Параметр), и, в этом случае, значение параметра передается с помощью УстановитьТекстовыйПараметр. В такой ситуации это равноценно val = :Параметр (сервер просто заменит IN на =).
Либо, если список возможных значений не очень большой, то вместо УложитьСписокОбъектов гораздо эффективней использовать конструкцию
val IN (:Параметр1, :Параметр2, ... , :ПараметрN).
18 - 15.11.2012 - 14:38
Но и в этом случае надо смотреть по ситуации на конкретных данных.
Короче, открываешь студию и эксперементируешь с разными вариантами на реальных данных с анализом плана выполнения запроса.


К списку вопросов






Copyright ©, Все права защищены