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
|
Но и в этом случае надо смотреть по ситуации на конкретных данных. Короче, открываешь студию и эксперементируешь с разными вариантами на реальных данных с анализом плана выполнения запроса. | |
| Интернет-форум Краснодарского края и Краснодара |