Имя: Пароль:
1C
1С v8
v8: Запрос
, ,
0 gosn1ck
 
07.04.12
15:03
Здравствуйте, в справочнике есть табличная часть в которой есть реквизит с типом булево. нужно получить список элементов справочника, когда все записи в табличной части (реквизита с типом булево) имеют значение ИСТИНА.
1 GROOVY
 
07.04.12
15:04
Ты свою тему завтра от этой отличишь: v8: Запрос ?
2 Рэйв
 
07.04.12
15:05
(1)Уже отличишь:)
3 GROOVY
 
07.04.12
15:06
ВЫБРАТЬ РАЗЛИЧНЫЕ
Ссылка
ИЗ
Справочник.НазваниеСправочник.НазваниеТЧ
ГДЕ
ИмяПоляСБулевом
4 GROOVY
 
07.04.12
15:07
А когда все... Ну это нереально... Я сдаюсь.
5 gosn1ck
 
07.04.12
15:08
да, надо все, а не хотя бы 1...
6 Рэйв
 
07.04.12
15:10
Да все просто.Но нифига не кошерно
Запрос в цикле по каждому элементу, вернее его таб части
7 vinogradъ
 
07.04.12
15:13
в запросе булево перевести в 0-1, получить сумму по ТЧ, сравнить с кол-вом элементов в ТЧ
8 Ksandr
 
07.04.12
15:14
Как то так

Выбрать РАЗЛИЧНЫЕ
 Ссылка
Из Спр
 ЛЕВОЕ СОЕДИНЕНИЕ СПр.ТЧ КАК СпрТЧ
 ПО Спр.Ссылка = СпрТЧ.Ссылка
 И (НЕ РеквБУЛЕВО)
 
Где
 СпрТЧ.Ссылка ЕСТЬ NULL
9 Asmody
 
07.04.12
15:14
МИН/МАКС по булевым полям работает?
10 Рэйв
 
07.04.12
15:16
(8)Бред.
11 gosn1ck
 
07.04.12
15:18
сделал временную что-то в (3), сделал временную с обратным флагом. а потом
ОплЗаписи.Ссылка НЕ В(ВЫБРАТЬ РАЗЛИЧНЫЕ А.Ссылка ИЗ НеОплЗаписи КАК А)
12 Asmody
 
07.04.12
15:18
Кстати, что делать с элементами с пустой тч?
13 Рэйв
 
07.04.12
15:19
(12)Если делать запрос по ТЧ,то пустые тч вообще не попадут.
14 Asmody
 
07.04.12
15:21
(13) Так я у ТС спрашиваю, чтоб уточнил задачу
15 gosn1ck
 
07.04.12
15:25
всем спасибо :)
(9) работает, но как-то не очень ,)
16 Ksandr
 
07.04.12
15:26
(10) Обоснуй
17 Рэйв
 
07.04.12
15:27
(15)Ну что ты, родной. Нельзя быть чуть -чуть беременным.
или работает или нет.Чуть-Чуть- тут лишнее
18 Рэйв
 
07.04.12
15:28
(16)Собака выла, все луны картами любили ночью Атоса.
Обоснуй что тут не поэма?
19 КМ155
 
07.04.12
15:34
(15) а через Having не проще будет ?

ВЫБРАТЬ
   НоменклатураТест.Ссылка
   Из
   Справочник.Номенклатура.Тест КАК НоменклатураТест

СГРУППИРОВАТЬ ПО
   НоменклатураТест.Ссылка
Имеющие КОЛИЧЕСТВО(НоменклатураТест.НомерСтроки) = СУММА(ВЫБОР
           КОГДА НоменклатураТест.Буёк
               ТОГДА 1
           ИНАЧЕ 0
       КОНЕЦ)
20 ILM
 
гуру
07.04.12
15:34
(3) Что мешает использовать ВЫБОР и агрегатную функцию СУММА ?

СУММА(ВЫБОР КОГДА полеИстина ТОГДА 0 ИНАЧЕ 1 КОНЕЦ)
ИМЕЮЩИЕ СУММА()..
21 ILM
 
гуру
07.04.12
15:35
(19) Опередил чертяка )))
22 ILM
 
гуру
07.04.12
15:36
(19) Можно не сравнивать, если есть Ложь тогда сумма будет больше 0.
23 gosn1ck
 
07.04.12
15:36
(19) Спасибо! классная тема
24 КМ155
 
07.04.12
15:39
(22) =)
25 vinogradъ
 
07.04.12
15:48
(19)=(7), только ТС напрягаться не нужно)
26 alexhtn
 
08.04.12
13:36

ВЫБРАТЬ
   НастройкиОбменаДанными.Ссылка
ИЗ
   Справочник.НастройкиОбменаДанными КАК НастройкиОбменаДанными
ГДЕ
   НЕ НастройкиОбменаДанными.Ссылка В
               (ВЫБРАТЬ РАЗЛИЧНЫЕ
                   СправочникТЧ.Ссылка
               ИЗ
                   Справочник.НастройкиОбменаДанными.НастройкаВыгрузкиДанных КАК СправочникТЧ
               ГДЕ
                   СправочникТЧ.ЭтоНастройкаДляВыгрузки = ЛОЖЬ)
27 ILM
 
гуру
09.04.12
09:04
(26) Как вариант, но неоптимально, на больших объемах будет тормозить.
28 Ненавижу 1С
 
гуру
09.04.12
09:11
если в ТЧ нет вообще данных, можно считать что все значения ИСТИНА?
29 Buster007
 
09.04.12
09:15
сделать 2 вложенных запроса (кто хочет тот может делать виртуальные)
один запрос получает количество в табличной части, второй запрос получает количество в табличной части со значением Истина и внутренним соединением по Количеству и Ссылке
30 nuctoh
 
09.04.12
09:21
Работает стопудово:

ВЫБРАТЬ
   МИНИМУМ(ИмяТЧ.Ошибка) КАК Ошибка,
   ИмяТЧ.Ссылка
ИЗ
   Справочник.Имя.ТЧ КАК ИмяТЧ
СГРУППИРОВАТЬ ПО
   ИмяТЧ.Ссылка
ИМЕЮЩИЕ
   МИНИМУМ(ИмяТЧ.Ошибка) = ИСТИНА
31 nuctoh
 
09.04.12
09:22
Один простейший запрос, один акт насилия над базой - группировка. Все очень просто и быстро
32 Serg_1960
 
09.04.12
09:30
(отмечусь :) Лень-матушка конфиг открывать, и потому на словах: выбрать из справочника все ссылки не входящие в список (ссылки, у которых в табличной части есть не "истина).
33 alexhtn
 
09.04.12
09:38
(27) Даже на миллионе записей, этот запрос выполнится менее чем за секунду.
Для быстродействия можно добавить индекс по полю, которое булево.
34 Ненавижу 1С
 
гуру
09.04.12
09:39
(33) >>Для быстродействия можно добавить индекс по полю, которое булево
жесть, просто жесть
35 СноваЗдорова
 
09.04.12
09:47
(34) Да классный индекс будет по полю в котором всего два значения возможны ))
36 DimVad
 
09.04.12
09:54
Нормально будет работать вот такой запрос :

ВЫБРАТЬ РАЗЛИЧНЫЕ
Ссылка
ИЗ
Справочник.НазваниеСправочник.НазваниеТЧ
ГДЕ
НЕ (ИмяПоляСБулевом = Ложь)

Смысл его таков: "Получить все ссылки на элементы справочника НазваниеСправочник где в ТЧ НазваниеТЧ НЕТ НИ ОДНОГО с значением Ложь".
Если ТЧ пуста, то "тоже считается" (мне показалось, что ТС это и надо). Если надо, элементы справочника с пустой ТЧ можно отфильтровывать отдельно. И это не "бзик" 1С, так все и задумывалось, и это очень удобно.
37 DimVad
 
09.04.12
10:03
Сорри, не то скопировал (пробовал на документе в пробной базе):

Текст, типа такой:

ВЫБРАТЬ
   Ссылка
ИЗ
   Справочник.НазваниеСправочник КАК НазваниеСправочник
ГДЕ
   НЕ (НазваниеСправочник.НазваниеТЧ.ИмяПоляСБулевом = Ложь)

т.е. обращаемся к справочнику, а не к его ТЧ...
38 Ненавижу 1С
 
гуру
09.04.12
10:06
(37) надо же было так SQL извратить
39 DimVad
 
09.04.12
10:11
Да нет, если в качестве источника выбирается таблица табличной части - получаем классический SQL (потом можно избавиться от дублей ссылок группировкой), а если сам справочник, а в условиях идет ссылка на поле из табличной части - тогда там чуть чуть другой смысл. И это часто позволяет сильно упрощать запросы... люблю 1С...
40 Serg_1960
 
09.04.12
10:19
Совести у вас нет. В понедельник утром такие вопросы обсуждать :(
Написать проще и голову не ломать быстродействием... типа так:

ВЫБРАТЬ РАЗЛИЧНЫЕ
   ОсновноеСырьеСостав.Ссылка
ИЗ
   Справочник.ОсновноеСырье.Состав КАК ОсновноеСырьеСостав
ГДЕ
   ОсновноеСырьеСостав.Номенклатура.Услуга <> &Услуга
41 DimVad
 
09.04.12
10:23
Совести у нас точно нет, но Ваш код не прокатит, сорри. Смотрите, пусть в ТЧ две записи, одна удовлетворяет условию, а другая - нет. По Вашему способу наш ТС получит ссылку на этот элемент, а ему ее как раз и надо отфильтровывать.
42 Kashemir
 
09.04.12
10:31
Имеющие  Минимум(Спр.булево) = Истина
43 nuctoh
 
09.04.12
10:33
Чего тут обсуждать? Код:

ВЫБРАТЬ
   МИНИМУМ(ИмяТЧ.Ошибка) КАК Ошибка,
   ИмяТЧ.Ссылка
ИЗ
   Справочник.Имя.ТЧ КАК ИмяТЧ
СГРУППИРОВАТЬ ПО
   ИмяТЧ.Ссылка
ИМЕЮЩИЕ
   МИНИМУМ(ИмяТЧ.Ошибка) = ИСТИНА

работает. И работает как надо
44 nuctoh
 
09.04.12
10:34
Блин, реквизит Ошибка забыл переименовать ))
45 fisher
 
09.04.12
10:35
По факту, думаю что производительность одинаковая будет что через ИМЕЮЩИЕ, что через коррелирующий подзапрос.
46 nuctoh
 
09.04.12
10:47
Посмотри план в профайлере, убедись в неправоте
47 Serg_1960
 
09.04.12
11:01
(41) Соори, DimVad , данный запрос следует рассматривать в контексте сказанного в (32).

Вот полный текст (не оптимально, признаю, но должно показать сырье, где в составе сырья нет услуг):

   Запрос = Новый Запрос();
   Запрос.Текст =
   "ВЫБРАТЬ
   |    ОсновноеСырье.Ссылка
   |ИЗ
   |    Справочник.ОсновноеСырье КАК ОсновноеСырье
   |ГДЕ
   |    (НЕ ОсновноеСырье.Ссылка В
   |                (ВЫБРАТЬ РАЗЛИЧНЫЕ
   |                    Список.Ссылка
   |                ИЗ
   |                    Справочник.ОсновноеСырье.Состав КАК Список
   |                ГДЕ
   |                    Список.Номенклатура.Услуга = ИСТИНА))";
48 zak555
 
09.04.12
11:27
(43) какая разница между минимум и максимум ?
49 nuctoh
 
09.04.12
11:29
Условие
МИНИМУМ(ИмяТЧ.Булево) = ИСТИНА
выполняется, только когда все элементы ТЧ = ИСТИНА, что и требовалось в ТЗ

Условие
МАКСИМУМ(ИмяТЧ.Булево) = ИСТИНА
выполняется, если хотя бы один из элементов ТЧ = ИСТИНА, что по ТЗ неприемлемо
50 zak555
 
09.04.12
11:33
(49) точно

Функция вычисляет минимальное значение из ВСЕХ попавших в выборку значений поля.
51 nuctoh
 
09.04.12
11:33
(47) Цель достигаетяс одним запросом с обращением к таблице ОсновноеСырье.Состав, без дерганья таблицы ОсновноеСырье. Кто нибудь когда нибудь научится брать в расчет оптимизацию производительности кода или нет?
52 Serg_1960
 
09.04.12
11:35
(51) Нет. Утром в понедельник - нет. Пусть оптимизатор запроса голову себе ломает :)
53 nuctoh
 
09.04.12
11:37
(50) А благодаря условию ИМЕЮЩИЕ сначала пройдет свертка с вычислением минимального значения реквизита Булево для каждой ссылки, и только потом - отсев нужных полей по условию.
54 nuctoh
 
09.04.12
11:38
(52) Жаль что у оптимизатора запросов нет хранимки "РасстрелятьКодера"
55 DimVad
 
09.04.12
11:42
Да, Вы совершенно правы, Serg_1960. Ваш путь наверняка решит проблему. Просто я читал, что использование подзапросов - самый неоптимальный с точки зрения ресурсов сервака. Оптимизатор у нас, конечно же, есть. Вот только 1С-ка бывает вылетает на запросах такого типа... Пипец памяти, говорит... Даже тоже самое но с помощью временных таблиц - гораздо оптимальнее. Я же написал запрос, который вернет тоже самое, что и Ваш:

   Запрос.Текст =
   "ВЫБРАТЬ
   |    ОсновноеСырье.Ссылка
   |ИЗ
   |    Справочник.ОсновноеСырье КАК ОсновноеСырье
   |ГДЕ
   |НЕ (Справочник.ОсновноеСырье.Состав.Услуга = ИСТИНА)");

Ибо по смыслу - тоже самое. Но короче и память экономит.
56 Ненавижу 1С
 
гуру
09.04.12
11:44
(55) не обольщайся, там скрытый под запрос
57 Serg_1960
 
09.04.12
11:48
ммм... не надо было мне на форум заходить, людей смущать... по утрам, мой извращённый мозг способен родить и не такое...

   "ВЫБРАТЬ
   |    Список.Ссылка КАК Ссылка,
   |    МАКСИМУМ(Список.НомерСтроки) КАК КоличествоСтрок,
   |    СУММА(ВЫБОР
   |            КОГДА Список.Номенклатура.Услуга = ИСТИНА
   |                ТОГДА 1
   |            ИНАЧЕ 0
   |        КОНЕЦ) КАК КоличествоУслуг
   |ИЗ
   |    Справочник.ОсновноеСырье.Состав КАК Список
   |
   |СГРУППИРОВАТЬ ПО
   |    Список.Ссылка
   |
   |ИМЕЮЩИЕ
   |    МАКСИМУМ(Список.НомерСтроки) = СУММА(ВЫБОР
   |            КОГДА Список.Номенклатура.Услуга = ИСТИНА
   |                ТОГДА 1
   |            ИНАЧЕ 0
   |        КОНЕЦ)";
58 nuctoh
 
09.04.12
11:49
(55) Там скрытый подзапрос - +1
Еще момент, этот запрос вернет все элементы справочника ОсновноеСырье, у которых в ТЧ Состав есть хоть одна строка, имеющая Услуга = ЛОЖЬ. То есть запрос не решает первоначальной задачи
59 zak555
 
09.04.12
11:49
(57) а НомерСтроки всегда идёт по порядку ?
60 DimVad
 
09.04.12
11:49
Я имел вылеты на явных вложенных запросах с использованием "В". После переделки вот на такой скрытый подзапрос - вылеты пропали. Может бы, Вы и правы, ибо один случай нифига не статистика. Ну чтож, если вылеты опять будут - переделаю под временные таблицы. Способ железобетонный и "плоский" (в смысле - "очень наглядный").
61 nuctoh
 
09.04.12
11:49
(57) твой воспаленный понедельником разум забыл заюзать ADODB и нативный запрос к СУБД
62 DimVad
 
09.04.12
11:50
Так ведь и надо "показать сырье, где в составе сырья нет услуг". Т.е. Услуга = ЛОЖЬ - это и надо показывать...
63 adron
 
09.04.12
11:52
Выбрать
   ТЧ.Ссылка
из
   справочники.тест1.ТЧ КАК ТЧ
Где
НЕ ТЧ.Ссылка В (
выбрать
   ТЧ.Ссылка
из
   справочники.тест1.ТЧ КАК ТЧ
Где
   ТЧ.Услуга = ложь)
64 nuctoh
 
09.04.12
11:53
(62) Дак может быть такое чудо:
Сырье1
Стр.1 Песок
Стр.2 Цемент
Стр.3 Смешивание (Услуга = ИСТИНА)

Твой запрос выберет Сырье1, но по ТЗ оно выбираться не должно, т.к. есть услуга
65 zak555
 
09.04.12
11:54
(63) так тут два запроса
66 Serg_1960
 
09.04.12
11:55
(59) В запросах - нет, не по порядку. Если надо по порядку - надо сортировать по номеру.

(61) Всё, убедил. Убил. Это был контрольный выстрел - и мой мозг взорвался от терминов, использованных тобой.

PS: а не хило развод заводит, да? :)
67 nuctoh
 
09.04.12
11:56
ВЫБРАТЬ
   МИНИМУМ(ОсновноеСырьеСостав.Услуга) КАК Услуга,
   ОсновноеСырьеСостав.Ссылка
ИЗ
   Справочник.ОсновноеСырье.Состав КАК ОсновноеСырьеСостав
СГРУППИРОВАТЬ ПО
   ОсновноеСырьеСостав.Ссылка
ИМЕЮЩИЕ
   МАКСИМУМ(ОсновноеСырьеСостав.Услуга) = ЛОЖЬ

Вот обращение к одной таблице - ОсновноеСырьеСостав, без всяких соединений, подзапросов и вирт. таблиц и выбор только того, что нужно
68 Serg_1960
 
09.04.12
11:59
(67) Только одно замечание: а зачем "МИНИМУМ(ОсновноеСырьеСостав.Услуга) КАК Услуга" ?
69 nuctoh
 
09.04.12
11:59
Ошибочка в запрос закралась - в первой строке МАКСИМУМ вместо МИНИМУМ надобно вписать

(66) Не выдержал, бедняжка, мой развод коварней был?
70 Serg_1960
 
09.04.12
12:01
(69) Не, не угадал. Не все способны заметить наш тонкий юмор :)
71 nuctoh
 
09.04.12
12:02
Флуд пошел, модеры такое не любят
72 zak555
 
09.04.12
12:05
(66) > не по порядку

я имею ввиду : всегда, когда создаёшь док с тч не будет пропусков номерах строки
73 nuctoh
 
09.04.12
12:07
(72) Не будет пропусков. Нумерация всегда равномерненькая с 1 по ТЧ.Количество()
74 DimVad
 
09.04.12
12:30
nuctoh, Ваш способ шикарный, сенькс. Он еще автоматом отбросит элементы справочников с пустой ТЧ...
75 nuctoh
 
09.04.12
12:49
А в условии сказано не НЕТ услуг, а ВСЕ элементы - НЕ услуги. Стало быть, элементы по логике должны быть
76 nuctoh
 
09.04.12
12:50
Имею в виду изначальное условие задачи
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший