1. extrim-style 7 10.10.18 10:55 Сейчас в теме

Последовательный условный запрос

В запросе необходимо выполнить поиск по коду в справочнике, а если ничего не найдено, то по наименованию. Необходимо выполнить это одним запросом и, желательно, по возможности, не нагружать базу поиском по наименованию, если найден элемент по коду. Как это реализовать?
Ответы
Избранное Подписка Сортировка: Древо
3. vadim1011985 46 10.10.18 11:03 Сейчас в теме
(1) Я бы предложил через условие
ГДЕ НужныйСправочник.Код = &Код ИЛИ НужныйСправочник.Наименование ПОДОБНО %&Наименование%

(или НужныйСправочник.Наименование = &Наименование)
4. alex-l19041 9 10.10.18 11:08 Сейчас в теме
(3) где-то читал, что при использовании ИЛИ неявно используется ОБЪЕДИНИТЬ. Тогда получиться что второе условие отработает для всего справочника
11. Sashares 1 10.10.18 11:36 Сейчас в теме
(4)Да и ладно.
Все равно запроса будет 2.
Добавить в выборку поле Выбор когда Код = &Код тогда 1 иначе 2 конец.
Отсортировать по этому полю и выбрать 1 запись.
12. extrim-style 7 10.10.18 11:42 Сейчас в теме
(11) это похоже на решение, рассматривал его, но есть ещё некоторые нюансы, которые не в рамках этой темы
5. extrim-style 7 10.10.18 11:09 Сейчас в теме
(1) ИЛИ не подходит, т.к. нужно вернуть ТОЛЬКО по коду или ТОЛЬКО по наименованию
(2) Думаю, не обязательно формировать такую громоздкую таблицу. В данном случае, наверное, можно обойтись соединениями.
Вопрос в том, как лучше проверить результат подзапроса? И есть ли возможность минимизировать второй подзапрос (по наименованию) с помощью условий, в случае если первый подзапрос возвращает хотя бы 1 строку.
13. RocKeR_13 432 10.10.18 11:45 Сейчас в теме
(1) Вы в запрос таблицу кодов и наименований передаете или только один код/наименование?
Во втором случае логично использовать НайтиПоКоду() и в случае пустой ссылки уже искать по наименованию.
В первом случае что-то такое можно:
ВЫБРАТЬ
	ТаблицаКодов.Код КАК Код,
	ТаблицаКодов.Наименование КАК Наименование
ПОМЕСТИТЬ Таблица
ИЗ
	&ТаблицаКодов КАК ТаблицаКодов
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Таблица.Код КАК Код,
	Таблица.Наименование КАК Наименование,
	Номенклатура.Ссылка КАК Ссылка
ПОМЕСТИТЬ ПоискПоКоду
ИЗ
	Таблица КАК Таблица
		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
		ПО Таблица.Код = Номенклатура.Код
;

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


В запрос передаете таблицу с колонками "Код" и "Наименование", первым запросом помещаете во временную таблицу, потом делаете левое соединение по коду и, наконец, выбираете все из найденного вторым пакетом по коду+левым соединением добавляете ссылки, которые по коду не нашлись
14. extrim-style 7 10.10.18 11:54 Сейчас в теме
(13) 1. поиск не только по коду, это я упростил задачу
2. в случае, если найден 1 по коду и 1 по наименованию, то запрос вернёт оба, а нужен 1 по коду в данном примере
15. RocKeR_13 432 10.10.18 12:01 Сейчас в теме
(14) нет, в моем примере если по коду найден элемент, то по наименованию не будет уже искать. Хотя...другое дело, что левое соединение с условием "ПОДОБНО" тут все равно будет неоптимальным, но это сейчас исправим
16. RocKeR_13 432 10.10.18 12:11 Сейчас в теме
(14) Вот такой запрос имеем:
ВЫБРАТЬ  //помещаем таблицу-параметр в ВТ
	ТаблицаКодов.Код КАК Код,
	ТаблицаКодов.Наименование КАК Наименование
ПОМЕСТИТЬ Таблица
ИЗ
	&ТаблицаКодов КАК ТаблицаКодов
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ //ищем по коду
	Таблица.Код КАК Код,
	Таблица.Наименование КАК Наименование,
	Номенклатура.Ссылка КАК Ссылка
ПОМЕСТИТЬ ПоискПоКоду
ИЗ
	Таблица КАК Таблица
		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
		ПО Таблица.Код = Номенклатура.Код
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ //ищем по наименованию то, что не нашли по коду
	ПоискПоКоду.Код КАК Код,
	ПоискПоКоду.Наименование КАК Наименование,
	Номенклатура.Ссылка КАК Ссылка
ПОМЕСТИТЬ НайдПоНаименованию
ИЗ
	ПоискПоКоду КАК ПоискПоКоду
		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
		ПО (Номенклатура.Наименование ПОДОБНО ПоискПоКоду.Наименование)
			И (ПоискПоКоду.Ссылка ЕСТЬ NULL)
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ //в таблице поиска по коду в колонке "Ссылка" заменяем NULL на ссылки из таблицы найденных по наименованию
	ПоискПоКоду.Код КАК Код,
	ПоискПоКоду.Наименование КАК Наименование,
	ЕСТЬNULL(ПоискПоКоду.Ссылка, НайдПоНаименованию.Ссылка) КАК Ссылка
ИЗ
	ПоискПоКоду КАК ПоискПоКоду
		ЛЕВОЕ СОЕДИНЕНИЕ НайдПоНаименованию КАК НайдПоНаименованию
		ПО (ПоискПоКоду.Код = НайдПоНаименованию.Код
				И ПоискПоКоду.Наименование = НайдПоНаименованию.Наименование)
Показать


На скринах время выполнения прошлого варианта и текущего
Прикрепленные файлы:
alex-l19041; Sashares; +2 Ответить
17. extrim-style 7 10.10.18 12:24 Сейчас в теме
(16) можно было использовать объединение. Мне не нужны оба, мне нужно только(!) по коду ИЛИ только(!) по наименованию.
18. catena 96 10.10.18 12:27 Сейчас в теме
(17)В коде в (16) по наименованию соединяются только те элементы, которые не были найдены по коду (ПоискПоКоду.Ссылка ЕСТЬ NULL), что не так?
19. RocKeR_13 432 10.10.18 12:28 Сейчас в теме
(17) То ли я вас не пойму... Какие оба? Уже в запросе комментарии прописал, что делает тот или иной пакет На примере на входе таблица с одной строкой, на выходе - также одна строка. И как хотите объединять?
20. Sashares 1 10.10.18 12:41 Сейчас в теме
2. alex-l19041 9 10.10.18 11:01 Сейчас в теме
надо все НЕ найденные по коду поместить во временную таблицу. Поиск по наименованию делать только по этой таблице
6. user633533_encantado 2 10.10.18 11:10 Сейчас в теме
Элементарная задача: пакет запросов, сначала ищем по коду, потом то что не нашли ищем по наименованию.
7. extrim-style 7 10.10.18 11:12 Сейчас в теме
(6) как проверять, что что-то нашлось? и как не проверять по наименованию, если нашлось?
8. user633533_encantado 2 10.10.18 11:14 Сейчас в теме
(7) Первый запрос сделай так чтобы он обязательно вернул результат, например одно из полей это сам параметр запроса. Вторым запросом ищи только то, что имеет вместо номенклатуры null.
9. extrim-style 7 10.10.18 11:31 Сейчас в теме
(8) а как потом выбрать только первый или только второй? (или я что-то не понял)
10. user633533_encantado 2 10.10.18 11:33 Сейчас в теме
(9) Второй пакет будет содержать два запроса, в одном отобрана номенклатура, которая была найдена первым запросом, второй только та, что не найдена.
21. Stackmann 10.10.18 15:42 Сейчас в теме
Я бы делал как-то так:

	Запрос.Текст = 
		"ВЫБРАТЬ
		|	ТабКодов.Код,
		|	ТабКодов.Наименование
		|ПОМЕСТИТЬ ВыбКодыИНаименования
		|ИЗ
		|	&ТабКодов КАК ТабКодов
		|;
		|
		|////////////////////////////////////////////////////////////­////////////////////
		|ВЫБРАТЬ
		|	Номенклатура.Ссылка,
		|	ВыбКодыИНаименования.Код,
		|	ВыбКодыИНаименования.Наименование
		|ПОМЕСТИТЬ НоменклатураПоКоду
		|ИЗ
		|	ВыбКодыИНаименования КАК ВыбКодыИНаименования
		|		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
		|		ПО (Номенклатура.Код В
		|				(ВЫБРАТЬ
		|					ВыбКодыИНаименования.Код
		|				ИЗ
		|					ВыбКодыИНаименования))
		|			И ВыбКодыИНаименования.Код = Номенклатура.Код
		|;
		|
		|////////////////////////////////////////////////////////////­////////////////////
		|ВЫБРАТЬ
		|	НоменклатураПоКоду.Ссылка
		|ИЗ
		|	НоменклатураПоКоду КАК НоменклатураПоКоду
		|ГДЕ
		|	НЕ НоменклатураПоКоду.Ссылка ЕСТЬ NULL 
		|
		|ОБЪЕДИНИТЬ ВСЕ
		|
		|ВЫБРАТЬ
		|	Номенклатура.Ссылка
		|ИЗ
		|	Справочник.Номенклатура КАК Номенклатура
		|ГДЕ
		|	Номенклатура.Наименование В
		|			(ВЫБРАТЬ
		|				НоменклатураПоКоду.Наименование
		|			ИЗ
		|				НоменклатураПоКоду
		|			ГДЕ
		|				НоменклатураПоКоду.Ссылка ЕСТЬ NULL )";
Показать
Оставьте свое сообщение
Новые вопросы с вознаграждением
Автор темы объявил вознаграждение за найденный ответ, его получит тот, кто первый поможет автору.

Вакансии

Программист 1С
Нижний Новгород
зарплата от 120 000 руб.
Полный день

Программист 1С
Санкт-Петербург
зарплата от 120 000 руб.
Полный день

Программист 1С
Новосибирск
зарплата от 80 000 руб. до 100 000 руб.
Полный день

Системный аналитик
Новосибирск
зарплата от 80 000 руб. до 100 000 руб.
Полный день

Программист 1С
Салехард
зарплата от 80 000 руб. до 200 000 руб.
Полный день