Имя: Пароль:
1C
 
Как можно оптимизировать запрос?
0 program345
 
21.04.25
10:58
привет! Конфа - розница. Как сделать проще?


Есть запрос, выбирающий пользователей из справочника ГруппыДоступа с определенными профилями групп доступа.

1. ВТ1: выбираю Группы пользователей из ГруппДоступа
2. ВТ2: Выбираю пользователей из нужных ГруппПользователей
3. Выборка: получаю пользователей из ГруппДоступа и объединяю их с пользователями нужных группПользователей. С общим условием по нужным ГруппамДоступа.


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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ГруппыПользователейСостав.Ссылка КАК ГруппаПользователей,
	ГруппыПользователейСостав.Пользователь КАК ПользовательГруппыПользователей
ПОМЕСТИТЬ ВТ_ПользователиИзНужныхГруппДоступа
ИЗ
	Справочник.ГруппыПользователей.Состав КАК ГруппыПользователейСостав
ГДЕ
	ГруппыПользователейСостав.Ссылка В
			(ВЫБРАТЬ
				ВТГруппыПользИЗГруппДоступа.Пользователь КАК Пользователь1
			ИЗ
				ВТГруппыПользИЗГруппДоступа КАК ВТГруппыПользИЗГруппДоступа)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
	ЕСТЬNULL(ВТ_ПользователиИзНужныхГруппДоступа.ПользовательГруппыПользователей, "НАЛЛ") КАК ПользовательГруппыПользователей,
	ЕСТЬNULL(ВТ_ПользователиИзНужныхГруппДоступа.ГруппаПользователей, "НАЛЛ") КАК ГруппаПользователей
ИЗ
	Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ПользователиИзНужныхГруппДоступа КАК ВТ_ПользователиИзНужныхГруппДоступа
		ПО ГруппыДоступаПользователи.Пользователь = ВТ_ПользователиИзНужныхГруппДоступа.ГруппаПользователей
ГДЕ
	НЕ ГруппыДоступаПользователи.Ссылка В (&РазрешенныеГруппыДоступа)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ РАЗЛИЧНЫЕ
	ГруппыДоступаПользователи.Пользователь,
	NULL
ИЗ
	Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
ГДЕ
	ГруппыДоступаПользователи.Пользователь ССЫЛКА Справочник.Пользователи

1 maxab72
 
21.04.25
10:27
Заменить ЛЕВОЕ соединение на ВНУТРЕННЕЕ
2 GANR
 
21.04.25
10:28
(0) ТвоеПоле IS NULL чем не устраивает?
3 program345
 
21.04.25
10:30
(2) хочу сделать чтобы не выводились лишние строки. При обходе результатов будет цепляться за тип объекта.
4 Мультук
 
гуру
21.04.25
10:30
(0)

Например
В первом подзапросе меняем соединение на ВНУТРЕННЕЕ
Второй подзапрос -- выкидываем. Нам же NULL не нужны ?

ВЫБРАТЬ РАЗЛИЧНЫЕ
	ВТ_ПользователиИзНужныхГруппДоступа.ПользовательГруппыПользователей КАК ПользовательГруппыПользователей,
	ВТ_ПользователиИзНужныхГруппДоступа.ГруппаПользователей КАК ГруппаПользователей
ИЗ
	Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ПользователиИзНужныхГруппДоступа КАК ВТ_ПользователиИзНужныхГруппДоступа
		ПО ГруппыДоступаПользователи.Пользователь = ВТ_ПользователиИзНужныхГруппДоступа.ГруппаПользователей
ГДЕ
	НЕ ГруппыДоступаПользователи.Ссылка В (&РазрешенныеГруппыДоступа)

5 GANR
 
21.04.25
10:32
(3) Ну и добавь НЕ ТвоеПоле IS NULL в фильтры запроса.
6 program345
 
21.04.25
10:32
(1) спасибо, помогло!
7 Волшебник
 
21.04.25
10:42
Правильный запрос:

ВЫБРАТЬ
	Ссылка КАК Пользователь,
	ГруппаПользователей КАК ГруппаПользователей
ИЗ
	Справочник.ГруппыДоступа.Пользователи
ГДЕ Ссылка В (&РазрешенныеГруппыДоступа)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ &ТекущийПользователь,
	NULL
8 breezee
 
21.04.25
10:43
Надо посмотреть план и понять что не так. Почему решили оптимизировать данный запрос?
9 program345
 
21.04.25
10:52
(8) есть ощущение что изобретаю велосипед.
10 program345
 
21.04.25
11:03
(4) с помощью подзапросов получаю значения пользователей в одну колонку (иначе они выходят в разных).
11 Волшебник
 
21.04.25
11:06
(4) меня смущает НЕ в этом условии:
ГДЕ НЕ ГруппыДоступаПользователи.Ссылка В (&РазрешенныеГруппыДоступа)
12 program345
 
21.04.25
11:27
(7) ваш пост мне навеял это:

ВЫБРАТЬ РАЗЛИЧНЫЕ
	ГруппыДоступаПользователи.Пользователь КАК Пользователь,
	NULL КАК Ссылка
ПОМЕСТИТЬ ВТ_СписокРазрСотр
ИЗ
	Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
ГДЕ
	НЕ ГруппыДоступаПользователи.Ссылка В (&ГруппыДоступа)
	И ГруппыДоступаПользователи.Пользователь ССЫЛКА Справочник.Пользователи

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	ГруппыПользователейСостав.Пользователь,
	ГруппыПользователейСостав.Ссылка
ИЗ
	Справочник.ГруппыПользователей.Состав КАК ГруппыПользователейСостав
ГДЕ
	ГруппыПользователейСостав.Ссылка В
			(ВЫБРАТЬ
				ГруппыДоступаПользователи.Пользователь КАК Пользователь
			ИЗ
				Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
			ГДЕ
				ГруппыДоступаПользователи.Пользователь ССЫЛКА Справочник.ГруппыПользователей
				И НЕ ГруппыДоступаПользователи.Ссылка В (&ГруппыДоступа))
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ВТ_СписокРазрСотр.Пользователь КАК Пользователь
ИЗ
	ВТ_СписокРазрСотр КАК ВТ_СписокРазрСотр
ГДЕ
	ВТ_СписокРазрСотр.Пользователь = &Пользователь

13 Волшебник
 
21.04.25
11:28
(12) У Вас неправильное условие
14 program345
 
21.04.25
11:32
(11) по условиям тз решили что пользователи которые имеют определенные права ГруппДоступа не могут иметь возможности редактирования. Однако часто Пользователь имеет несколько групп доступа, и чтобы выбрать нужных использую НЕ. В Запросе выходят все кто имеет право на редактирование. Можно было не использовать НЕ, но там ролей десятки, а тут всего два.
15 Ненавижу 1С
 
гуру
21.04.25
11:40
(0) так вы все равно не получите ВСЕХ пользователей профиля (входящих косвенно, через подчиненные группы). Попробуйте такое:

ВЫБРАТЬ РАЗЛИЧНЫЕ
    СоставыГруппПользователей.Пользователь КАК Пользователь
ИЗ
    Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.СоставыГруппПользователей КАК СоставыГруппПользователей
        ПО (ГруппыДоступаПользователи.Пользователь = СоставыГруппПользователей.ГруппаПользователей
                И СоставыГруппПользователей.Используется)
ГДЕ
    ГруппыДоступаПользователи.Ссылка.Профиль = &Профиль
16 Волшебник
 
21.04.25
11:44
ВЫБРАТЬ
	ВЫБОР
		КОГДА &ТекущийПользователь В
				(ВЫБРАТЬ
					ГруппыДоступаПользователи.Пользователь
				ИЗ
					Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
				ГДЕ
					ГруппыДоступаПользователи.Ссылка В (&СписокЗапрещающихРолей))
			ТОГДА ЛОЖЬ
		ИНАЧЕ ИСТИНА
	КОНЕЦ КАК Доступ
17 Волшебник
 
21.04.25
11:59
Функция ЕстьДоступКРедактированию()
	
	Запрос = Новый Запрос("
		|ВЫБРАТЬ ПЕРВЫЕ 1
		|	Т.Ссылка КАК Роль
		|ИЗ
		|	Справочник.ГруппыДоступа.Пользователи КАК Т
		|ГДЕ
		|	Т.Ссылка В(&СписокЗапрещающихРолей)
		|	И Т.Пользователь = &ТекущийПользователь");
	
	СписокЗапрещающихРолей = Новый Массив;
	СписокЗапрещающихРолей.Добавить(Справочники.ГруппыДоступа.ЗапрещающаяРоль1);	
	СписокЗапрещающихРолей.Добавить(Справочники.ГруппыДоступа.ЗапрещающаяРоль2);	
	Запрос.УстановитьПараметр("СписокЗапрещающихРолей", СписокЗапрещающихРолей);
	
	Запрос.УстановитьПараметр("ТекущийПользователь", ПараметрыСеанса.ТекущийПользователь);
	
	РезультатЗапроса = Запрос.Выполнить();
	Разрешено = РезультатЗапроса.Пустой();
	
	Возврат Разрешено;
	
КонецФункции
18 program345
 
21.04.25
11:59
(13) какое? тут их 4 штуки.
Пользователь не знает, чего он хочет, пока не увидит то, что он получил. Эдвард Йодан