Запрос по контрагентам у которых не было продаж

1. sasha-asn 16.09.19 11:52 Сейчас в теме
Доброго времени суток эксперты!
Учусь писать запросы, так вот застрял на том как написать следующий запрос: вывожу всех контрагентов у которых не было продаж за период
ВЫБРАТЬ
	Контрагенты.Ссылка,
	Продажи.Стоимость,
	Продажи.ДокументПродажи
ИЗ
	РегистрНакопления.Продажи КАК Продажи
		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты
		ПО Продажи.Контрагент = Контрагенты.Ссылка
Где Продажи.Стоимость is null
Показать


Где я ошибаюсь?
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
6. danjer74 3 16.09.19 13:40 Сейчас в теме
(1)Выбрать контрагентов из регистра, выбрать контрагентов из справочника с условием ГДЕ Контрагенты.Ссылка НЕ В (Выборка из регистра)
7. nomad_irk 76 16.09.19 13:45 Сейчас в теме
(6)Это лишнее расходование ресурсов сервера SQL.

Соединение по индексируемым полям выполнится максимально быстро.
20. DrZombi 293 17.09.19 06:56 Сейчас в теме
(1)
ВЫБРАТЬ
    Контрагенты.Ссылка,
    Продажи.Стоимость,
    Продажи.ДокументПродажи
ИЗ
    РегистрНакопления.Продажи КАК Продажи
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты
        ПО Продажи.Контрагент = Контрагенты.Ссылка
Где ЕстьNull(Продажи.Стоимость, 0) = 0
Показать
31. Seraph6 17.09.19 13:53 Сейчас в теме
(1) Если у вас продажи "за период", то как минимум не хватает параметров в запросе к виртуальной таблице. Без них он вам за всю историю существования базы выдаст данные. Ну и да, соединение в обратную сторону.

ВЫБРАТЬ
    Контрагенты.Ссылка,
    Продажи.Стоимость,
    Продажи.ДокументПродажи
ИЗ
    Справочник.Контрагенты КАК Контрагенты
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи(&ДатаНач, &ДатаКон, , ) КАК Продажи
        ПО Продажи.Контрагент = Контрагенты.Ссылка
Где Продажи.Стоимость ЕСТЬ NULL
Показать
2. nomad_irk 76 16.09.19 11:56 Сейчас в теме
В выборе основной таблицы. В вашем случае основной таблицей должна быть Справочник.Контрагенты
Seraph6; Fox-trot; +2 Ответить
4. seevkik 8 16.09.19 11:58 Сейчас в теме
(2)Ну или в соединении - указать правое)
FetisovAN; +1 Ответить
3. YannikAlx 43 16.09.19 11:58 Сейчас в теме
Ошибаетесь в левом-правом....
Вы же хотите увидеть Контрагентов, так и выбирайте ИЗ Справочник.Контрагенты
А не из регистра....
А регистр пристегивается к справочнику для того чтобы проверить, что в нем нету ничего
5. seevkik 8 16.09.19 12:00 Сейчас в теме
И второе и третье поле очень таки лишние
Я бы сгруппировал регистр продаж по контрагентам, запихал в ВТ и соединил ВТ со справочником
8. Vovan58 65 16.09.19 17:09 Сейчас в теме
Жестоко Вы как...
Делайте проще и еще проще :
Простая логика - сначала выбираем всех контрагентов у которых были покупки за период во временную таблицу :

ВЫБРАТЬ РАЗЛИЧНЫЕ
	Продажи .Контрагент КАК Покупатель
ПОМЕСТИТЬ ВТ_Покупатели
ИЗ
	РегистрНакопления.Продажи КАК Продажи 
ГДЕ
	Продажи .Сумма > 0
	И Продажи.Период МЕЖДУ &ПериодНачало И &ПериодОкончание
;

Показать


а за тем связываем со всеми контрагентами в еще одной временной таблице

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

Показать


а потом применяем условие

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ВТ_ВсеКонтрагенты.Ссылка КАК Контрагент
ИЗ
	ВТ_ВсеКонтрагенты КАК ВТ_ВсеКонтрагенты
ГДЕ
	ВТ_ВсеКонтрагенты.Купил = ЛОЖЬ


Вуаля.
unknow_user; +1 Ответить
9. nomad_irk 76 16.09.19 17:14 Сейчас в теме
(8)Для чего все это, если запрос может состоять из двух таблиц и левого соединения между ними?
37. unknow_user 26.03.20 07:08 Сейчас в теме
(8) Отличный вариант. Спасибо. Только поле купил лучше представить так:

.....
        ВЫБОР
		КОГДА ВТ_Покупатели.Покупатель = Контрагенты.Ссылка
			ТОГДА ИСТИНА
		ИНАЧЕ ЛОЖЬ
	КОНЕЦ КАК Купил
.....


А то условие не факт что сработает:

.....
       ГДЕ
             ВТ_ВсеКонтрагенты.Купил = ЛОЖЬ
10. Vovan58 65 16.09.19 17:35 Сейчас в теме
Левое соединение с условиями? А вы уверены, что в этом случае не получите ВНУТРЕННЕЕ СОЕДИНЕНИЕ?
13. nomad_irk 76 16.09.19 17:43 Сейчас в теме
(10)вы о чем сейчас вообще? Виртуальная таблица оборотов регистра накопления выдаст сразу нужный результат при левом соединении к справочнику контрагентов по равенству измерения регистра ссылке из справочника.
11. Vovan58 65 16.09.19 17:37 Сейчас в теме
И еще один вариант - первая таблица чаще всего будет виртуальная... И вот ее соединять лучше через временную...
unknow_user; +1 Ответить
12. Vovan58 65 16.09.19 17:38 Сейчас в теме
И если Вы внимательно посмотрите, то увидите сколько всего не так в первом запросе...
unknow_user; +1 Ответить
14. Vovan58 65 16.09.19 17:44 Сейчас в теме
Не рекомендуется... Попробуйте, когда у Вас любая серьезная таблица... Ждать будете до марковкинного...
unknow_user; acanta; +2 Ответить
15. nomad_irk 76 16.09.19 17:48 Сейчас в теме
(14)хорошо, если так любите временные таблицы, сделайте временную таблицу по оборотам, проиндексируйте поле контрагента и соедините опять же слева к справочнику контрагентов и ограничьте ГДЕ Обороты.Контрагент is null
38. unknow_user 26.03.20 09:33 Сейчас в теме
(15) И для полного счастья не забыть УНИЧТОЖИТЬ ВТ_Покупатели и ВТ_ВсеКонтрагенты
16. Vovan58 65 16.09.19 18:14 Сейчас в теме
Вопрос принципиально в ошибках : Вот запрос и результат:

ВЫБРАТЬ
	"Ассоль" КАК Контрагент
ПОМЕСТИТЬ ВТ_Контрагенты

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	"Комплесный"

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	"Другой"
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	"Ассоль" КАК Контрагент,
	10 КАК Сумма
ПОМЕСТИТЬ ВТ_Продажи

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

ВЫБРАТЬ
	"Комплексный",
	10

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

ВЫБРАТЬ
	"Комплексный",
	10
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ_Контрагенты.Контрагент КАК Контрагент
ИЗ
	ВТ_Продажи КАК ВТ_Продажи
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Контрагенты КАК ВТ_Контрагенты
		ПО ВТ_Продажи.Контрагент = ВТ_Контрагенты.Контрагент
ГДЕ
	ВТ_Продажи.Контрагент ЕСТЬ NULL
Показать


Запрос: ВТ_Продажи (Записей в результате: 0)
Контрагент

Теперь сделаем по другому : Левое соединение от Контрагентов :

ВЫБРАТЬ
	"Ассоль" КАК Контрагент
ПОМЕСТИТЬ ВТ_Контрагенты
ОБЪЕДИНИТЬ
ВЫБРАТЬ
	"Комплексный"
ОБЪЕДИНИТЬ
ВЫБРАТЬ
	"Любимый"
ОБЪЕДИНИТЬ
ВЫБРАТЬ
	"Другой"
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	"Ассоль" КАК Контрагент,
	10 КАК Сумма
ПОМЕСТИТЬ ВТ_Продажи

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

ВЫБРАТЬ
	"Комплексный",
	10

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

ВЫБРАТЬ
	"Комплексный",
	10
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ_Контрагенты.Контрагент КАК Контрагент
ИЗ
	ВТ_Контрагенты КАК ВТ_Контрагенты
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Продажи КАК ВТ_Продажи
		ПО ВТ_Контрагенты.Контрагент = ВТ_Продажи.Контрагент
ГДЕ
	ВТ_Продажи.Контрагент ЕСТЬ NULL
Показать


получим искомый результат (то что хотели):
Контрагент
Любимый
Другой

Но жизнь сложнее , нам необходимо выбирать продажи без возвратов :
и тогда простой вариант не катит :( :

ВЫБРАТЬ
	"Ассоль" КАК Контрагент
ПОМЕСТИТЬ ВТ_Контрагенты

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	"Комплексный"

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	"Любимый"

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	"Другой"
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	"Ассоль" КАК Контрагент,
	10 КАК Сумма
ПОМЕСТИТЬ ВТ_Продажи

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

ВЫБРАТЬ
	"Комплексный",
	10

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

ВЫБРАТЬ
	"Комплексный",
	10
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ_Контрагенты.Контрагент КАК Контрагент
ИЗ
	ВТ_Контрагенты КАК ВТ_Контрагенты
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Продажи КАК ВТ_Продажи
		ПО ВТ_Контрагенты.Контрагент = ВТ_Продажи.Контрагент
ГДЕ
	ВТ_Продажи.Контрагент ЕСТЬ NULL
	И ВТ_Продажи.Сумма > 0
Показать


получаем результат пустой.... Проверяйте
17. nomad_irk 76 16.09.19 18:23 Сейчас в теме
(16)
.....
ГДЕ
ВТ_Продажи.Контрагент ЕСТЬ NULL
И ВТ_Продажи.Сумма > 0

Вы сами-то поняли, чего хотите от машины?
То, что результат в данном случае пустой - логично. Что сказать-то хотели в итоге?
18. Vovan58 65 16.09.19 18:26 Сейчас в теме
Я и сказал, что левое соединение в последнем случае не работает!
19. nomad_irk 76 16.09.19 22:07 Сейчас в теме
(18)Вы прикалываетесь или реально не понимаете как работают виртуальная таблица оборотов регистра накопления?

Судя по тому, что вы написали, возвраты у вас регистрируются в том же регистре, что и продажи.
Если это так, то обороты дадут сразу результат с учетом возвратов. Если необходимо узнать количество именно возвратов, то выводим обороты, противоположные регистрации продаж.

Если возвраты регистрируются в другом регистре, то левое соединение контрагентов с оборотами этого регистра даст все возвраты. Если необходо узнать, по каким контрагентам не было возвратов, так же ограничивает запрос конструкцией ГДЕ ВозвратыОбороты.Контрагент IS NULL
21. DrZombi 293 17.09.19 06:57 Сейчас в теме
Держи, брат

ВЫБРАТЬ
    "Ассоль" КАК Контрагент
ПОМЕСТИТЬ ВТ_Контрагенты

ОБЪЕДИНИТЬ

ВЫБРАТЬ
    "Комплесный"

ОБЪЕДИНИТЬ

ВЫБРАТЬ
    "Другой"
;

////////////////////////////////////////////////////////////­­////////////////////
ВЫБРАТЬ
    "Ассоль" КАК Контрагент,
    10 КАК Сумма
ПОМЕСТИТЬ ВТ_Продажи

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

ВЫБРАТЬ
    "Комплексный",
    10

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

ВЫБРАТЬ
    "Комплексный",
    10
;

////////////////////////////////////////////////////////////­­////////////////////
ВЫБРАТЬ
    ВТ_Контрагенты.Контрагент КАК Контрагент
ИЗ
    ВТ_Продажи КАК ВТ_Продажи
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Контрагенты КАК ВТ_Контрагенты
        ПО ВТ_Продажи.Контрагент = ВТ_Контрагенты.Контрагент
ГДЕ
    ВТ_Продажи.Контрагент ЕСТЬ NULL
Показать
22. nomad_irk 76 17.09.19 07:19 Сейчас в теме
(21) чем дальше в лес, тем толще партизаны.....
YannikAlx; +1 Ответить
23. YannikAlx 43 17.09.19 09:16 Сейчас в теме
(22) либо день такой, либо просто все сошли с ума, кроме нас с вами!
Комментировать весь этот бред уже просто не хочется, даже мысль проскочила - может пятница (но календарь не дал такого шанса ;-_ )
nomad_irk; +1 Ответить
24. nomad_irk 76 17.09.19 09:17 Сейчас в теме
(23)Радует уже то, что я не одинок, а то уже было подозрение, что я что-то не понимаю :)
25. YannikAlx 43 17.09.19 09:29 Сейчас в теме
(24) А может все просто и им за количество строк кода стали платить , а мы с вами отстали?
Это кроме того , что в половине примеров вообще бред...

ВЫБРАТЬ
 Контрагенты.Ссылка
ИЗ
Справочник.Контрагенты КАК Контрагенты
ЛЕВОЕ СОЕДИНЕНИЕ  РегистрНакопления.Продажи КАК Продажи
             ПО Продажи.Контрагент = Контрагенты.Ссылка
Где Продажи.Стоимость is null
29. nomad_irk 76 17.09.19 13:20 Сейчас в теме
(25)У меня такое ощущение, что у них основная задача - загрузить SQL сервер по максимуму.....
26. Ditron 185 17.09.19 13:12 Сейчас в теме
ну я бы брал не стоимость в условии а количество (патамушо корректировки могут быть))) ну и обороты использовать, а не чистую таблицу
ВЫБРАТЬ
   Контрагенты.Ссылка
ИЗ
   Справочник.Контрагенты КАК Контрагенты
   ЛЕВОЕ СОЕДИНЕНИЕ  РегистрНакопления.Продажи.Обороты(<ну там параметры нужные, если что ))>) КАК Продажи
   ПО Контрагенты.Ссылка = Продажи.Контрагент
ИМЕЮЩИЕ
   ЕСТЬNULL(Продажи.КоличествоОборот, 0) = 0
Показать
27. nomad_irk 76 17.09.19 13:19 Сейчас в теме
(26) да хоспати.....для чего ИМЕЮЩИЕ? оно все равно не работает само по себе.
Для чего преобразование NULL к числу и сравнение с 0?
28. Ditron 185 17.09.19 13:20 Сейчас в теме
30. nomad_irk 76 17.09.19 13:22 Сейчас в теме
(28)да это паноптикум какой-то......
32. YannikAlx 43 17.09.19 14:18 Сейчас в теме
(28) Если продажи были в принципе то это уже не "наш" Контрагент, а наш именно тот которого в принципе нету в регистре Продажи, то есть NULL
потому его и ищем IS NULL
33. Indgo 410 18.09.19 16:12 Сейчас в теме
(26) Исправил
ВЫБРАТЬ
   Контрагенты.Ссылка
ИЗ
   Справочник.Контрагенты КАК Контрагенты
   ЛЕВОЕ СОЕДИНЕНИЕ  РегистрНакопления.Продажи.Обороты() КАК Продажи
   ПО Контрагенты.Ссылка = Продажи.Контрагент
group by Контрагенты.Ссылка
ИМЕЮЩИЕ
   sum(ЕСТЬNULL(Продажи.КоличествоОборот, 0)) = 0
Показать
34. nomad_irk 76 18.09.19 19:11 Сейчас в теме
(33) Ну для чего лишние телодвижения? SQL-сервер загнобить? :)
35. Indgo 410 18.09.19 19:26 Сейчас в теме
(34)
у для чего лишние телодвижения? SQL-сервер загнобить? :

без них никак. Имеющие - это же агригатная функция или тогда надо писать "где" если сервер жалко
36. nomad_irk 76 18.09.19 19:38 Сейчас в теме
(35)Это да, но все это - лишнее.
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот