![]() |
1cpp NOT IN (SELECT Как наложить условие "кроме выбранной группы" Если КромеНоменклатура = 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" результат пустая таблица. |
Закинь элементы из ВыбНоменклатура в список значений и по нему условие делать. |
По моему в Рез = Рез + " AND ($ДокС.Номенклатура <> :ВыбНоменклатура" надо писать #ВыбНоменклатура, а не с двоеточиес |
NOT($ДокС.Номенклатура IN (SELECT Val FROM #ВыбНоменклатура)) |
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 Итоги.Дата Может я что не доглядел? |
я не программист, но по моей логике операторы In и NotIn работают по булевой алгебре "Правда" <-> "Ложь"... если Value [b]пустое[/b] или NULL(?), то рассматриваемые операторы могут не сработать... я почему так думаю? чудес не бывает... когда работает f и не работает обратная f^(-1), то [b]пустышка[/b] находится вне рассматриваемого интервала... в данном случае - вне выбранной группы... если я не прав, то пусть старшие товарищи меня поправят (с) Топтыгин из к/ф "Ещё раз про любовь" |
Гена, вполне логично, тем более что это подтверждает практика. Просто не нашел правильного примера. Конечно можно запихнуть "все кроме" в список, но что-то пихать под миллион значений туда не хочется. Тем более для обычных запросов Условие (НЕ(ПеремЗапроса в ИмяЭлемента)) работае так же бысто (точнее так же медленно). Не подскажет форум с гуглом, придется идти к админу вылавливать во что преобразуется "Условие (НЕ(ПеремЗапроса в ИмяЭлемента))" |
для правильного примера достаточно запустить свой отчёт в другой короткой базе, например, в демо... если там работает NotIn, то мы правильно поставили диагноз рабочей базе и тогда просто останется вычистить там гнилую пустышку в номенклатуре или в доке, тем более, что этот флюк может портить жизнь и в других ситуациях... |
(0)Покажи, что возвращает Запрос.Отладка(1) и что в список пихаешь ЗЫ: ВыбНоменклатура.Выбран() = ? |
В 1С++ не силён, но что делает SELECT Val FROM #ВыбНоменклатура? По идее, надо селектить элементы, у которых родитель не равен выбранной группе, но это верно для 1 уровня, т.е. в группе нет вложенной группы, иначе придётся искать все вложенные группы.. |
(9) в #ВыбНоменклатура будут все элементы, принадлежащие выбранной группе на всех уровнях.. только и всего. [url]http://www.1cpp.ru/docum/icpp/html/ODBC.html#putobjectlist[/url] |
10 понятно. |
Прошу прощения. Ступил. Давно не смотрел, что выводит Запрос.Отладка(1). Просто в условия попадали два взаимоисключающих события. Спасибо Ёпрст. Все работает. Иду стреляться. Потратил 5 часов из-за своей невнимательности. Еще раз прошу прощения. |
все не осилил, но обычно пишу : 1 - IN () 2 - NOT IN () Без всяких не равно. Равно или не равно писать нельзя, надо писать IN - принадлежность к выборке |
13 USSR Если фильтр по одному элементу, то тоже IN Можно обосновать или дать ссылку? |
14-vovan519 >без разницы: "=" или "IN". Всё равно оптимизатор перведет IN в =. Правда оптимизатор потратит на это ресурсы, но очень не значительные. :) |
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 сек разницы нет, но все же. |
16-vovan519 >Некорректное сравнение. Ты сравнивал не IN и = , а УстановитьТекстовыйПараметр и УложитьСписокОбъектов. УстановитьТекстовыйПараметр просто подставляет патаметр в текст запроса, если грубо, то время тратится только на приведение параметра к типу строка и замене в тексте запроса самого параметра на его строковое представление. УложитьСписокОбъектов - формирует таблицу на сервере и заполняет её переданными данными, а затем сервер, при выполнении запроса произодит join с этой таблицей. Естественно эта операция стоит гораздо дороже. Я думаю, USSR имел ввиду несколько другое. Либо val IN (:Параметр), и, в этом случае, значение параметра передается с помощью УстановитьТекстовыйПараметр. В такой ситуации это равноценно val = :Параметр (сервер просто заменит IN на =). Либо, если список возможных значений не очень большой, то вместо УложитьСписокОбъектов гораздо эффективней использовать конструкцию val IN (:Параметр1, :Параметр2, ... , :ПараметрN). |
Но и в этом случае надо смотреть по ситуации на конкретных данных. Короче, открываешь студию и эксперементируешь с разными вариантами на реальных данных с анализом плана выполнения запроса. |
Текущее время: 09:32. Часовой пояс GMT +3. |