Форум на Kuban.ru (http://forums.kuban.ru/)
-   Территория 1С (http://forums.kuban.ru/f1040/)
-   -   замена подзапросов в селекте в 8.2 (http://forums.kuban.ru/f1040/zamena_podzaprosov_v_selekte_v_8_2_a-2457510.html)

pavlo 06.04.2012 08:20

замена подзапросов в селекте в 8.2
 
Просьба помочь проблема такая, есть следующее:
1. Регистр Сведений там Клиент и Активность булево, выбирается по значению Истина
2. Регистр Накопления оборотный и там Клиент, типУслуги и количество
так вот нужно как то выбрать только активных клиентов и по ним типУслуги (которой он пользовался максимально больше всех остальных)
Клиент - типУслуги
Клиент2 - типУслуги
и т.д.

На T-SQL сделал бы так, но так в 8.2 нельзя, никто не знает тогда как решить задачу?


ВЫБРАТЬ
КлиентыВКлубеСрезПоследних.Клиент КАК Клиент,
(ВЫБРАТЬ ПЕРВЫЕ 1 ПосещенияКлиентовОбороты.Занятие КАК Занятие ИЗ
РегистрНакопления.ПосещенияКлиентов.Обороты КАК ПосещенияКлиентовОбороты
ГДЕ ПосещенияКлиентовОбороты.Клиент = КлиентыВКлубеСрезПоследних.Клиент КАК Клиент
УПОРЯДОЧИТЬ ПО ПосещенияКлиентовОбороты.КоличествоОборот УБЫВ) КАК Занятие

ИЗ РегистрСведений.КлиентыВКлубе.СрезПоследних(, Присутствие) КАК КлиентыВКлубеСрезПоследних

Sadovnikov 06.04.2012 08:24

И на T-SQL так делать тоже нельзя.

pavlo 06.04.2012 08:42

чего это нельзя подзапрос сделать типа? :)
select
(select)
from

Sadovnikov 06.04.2012 08:43

Тормоза жуткие будут.

pavlo 06.04.2012 08:43

делал и не тормозит :)

pavlo 06.04.2012 08:45

да и не суть, другое дело как решить задачу :(

Sadovnikov 06.04.2012 08:45

Ну-ну... Твой Select будет выполняться на каждую строку выборки. И это - не будет тормозить?

Sadovnikov 06.04.2012 08:49

[em]как решить задачу[/em] - точно так же, как, например, работал бы с периодикой в семерке.

ТекстЗапроса = ТекстЗапроса + "
| LEFT JOIN (
| SELECT идПартия, Max(Дата) Дата
| FROM "+ИмяВторойБазы+".ЗалоговаяСтоимость Цены (NoLock)
| WHERE
| Дата <= '"+Формат(КонДата, "ДГГГГММДД")+"'
| GROUP BY идПартия
| ) ЦеныСДатами ON ЦеныСДатами.идПартия = "+Алиас+".Партия
| LEFT JOIN "+ИмяВторойБазы+".ЗалоговаяСтоимость Цены (NoLock) ON Цены.идПартия = ЦеныСДатами.идПартия AND Цены.Дата = ЦеныСДатами.Дата
|";

pavlo 06.04.2012 08:56

Знаю что на каждую строчку.
Олег, все от задачи зависит и там где это применимо очень даже реально помогает ;)

Buzz 06.04.2012 08:57

А первым подзапросом выбрать активных клиентов и внутренним соединением по клиенту к нему обороты прикрепить и выбрать макс количество не не покатит?

pavlo 06.04.2012 08:57

да и описал вариант, чтобы просто понятно было что нужно ;)

pavlo 06.04.2012 08:58

Buzz: нет не прокатит вернет толпу строк с группировкой по клиенту и услуге, а нужно только одну услугу, которой пользуется максимально часто этот клиент.

Sadovnikov 06.04.2012 08:59

[em]там где это применимо[/em] - согласен. Например, когда в выборке - одна-две строки. Но в (1) описана же другая ситуация, верно?

Sadovnikov 06.04.2012 09:00

(12) Ну посмотри на пример, что я показал.. 2 связывания нужно. В одном - граничные условия определяешь, во втором - данные выдергиваешь по этим условиям.

pavlo 06.04.2012 09:01

(8) что то не пойму как мне поможет получение срезапоследних виртуальной по сути, решить проблему? ;)
там проблема именно в оборотах как раз, как так получить по каждому клиенту максимальную услугу, но без остальных

pavlo 06.04.2012 09:03

(13) как раз там 4 строки :)

pavlo 06.04.2012 11:19

ну что ни у кого нет идей?

Sadovnikov 06.04.2012 11:22

А (8) и (14) чем не устроили?

pavlo 06.04.2012 13:23

Олег спасибо!
для истории оставлю решение, решил так :)

ВЫБРАТЬ
ПосещенияКлиентовОбороты.Клиент,
ПосещенияКлиентовОбороты.Занятие,
ПосещенияКлиентовОбороты.КоличествоОборот КАК КоличествоОборот
ПОМЕСТИТЬ РазличныеПоКлиентам
ИЗ
РегистрНакопления.ПосещенияКлиентов.Обороты КАК ПосещенияКлиентовОбороты
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
РазличныеПоКлиентам.Клиент,
МАКСИМУМ(РазличныеПоКлиентам.КоличествоОборот) КАК КоличествоОборот
ПОМЕСТИТЬ МаксимальныеПоКлиентам
ИЗ
РазличныеПоКлиентам КАК РазличныеПоКлиентам

СГРУППИРОВАТЬ ПО
РазличныеПоКлиентам.Клиент
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
РазличныеПоКлиентам.Клиент,
РазличныеПоКлиентам.Занятие
ПОМЕСТИТЬ ГотовыеМаксимальные
ИЗ
РазличныеПоКлиентам КАК РазличныеПоКлиентам
ВНУТРЕННЕЕ СОЕДИНЕНИЕ МаксимальныеПоКлиентам КАК МаксимальныеПоКлиентам
ПО РазличныеПоКлиентам.Клиент = МаксимальныеПоКлиентам.Клиент
И РазличныеПоКлиентам.КоличествоОборот = МаксимальныеПоКлиентам.КоличествоОборот
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ГотовыеМаксимальные.Клиент,
ГотовыеМаксимальные.Занятие
ИЗ
ГотовыеМаксимальные КАК ГотовыеМаксимальные
ГДЕ
ГотовыеМаксимальные.Клиент В
(ВЫБРАТЬ
КлиентыВКлубеСрезПоследних.Клиент
ИЗ
РегистрСведений.КлиентыВКлубе.СрезПоследних(, Активность
И Присутствие) КАК КлиентыВКлубеСрезПоследних)

Sadovnikov 06.04.2012 13:26

А зачем временные таблицы? Все в одном запросе же сделать можно.

Lexusss 06.04.2012 13:48

Мысля первая:
ВЫБРАТЬ
КлиентыВКлубеСрезПоследних.Клиент
ИЗ
РегистрСведений.КлиентыВКлубе.СрезПоследних(, Активность
И Присутствие)
покажет в том числе и не активных клиентов, которые раньше были активными.
Мысля вторая:
Достаточно одной временной таблицы РазличныеПоКлиентам при наличии более, чем двух измерений в этом регистре накопления. Если же в запросе перечислены все измерения, то временные таблицы вовсе будут тормозить выполнение запроса.

pavlo 09.04.2012 05:02

(20) потому как здесь это не получается решить в рамках задачи, по другому как то.
(21) срезпоследних с особенно параметром Присутствие никак не вернет Не активных.
Достаточно или нет, но примеров никто не дал досканальных, а что не пробовал лучше не получилось что то, как то напрягает малость извращенность запросов в 8.2 :)

Lexusss 09.04.2012 10:42

(22) [quote=pavlo1c;24458808]не получается решить в рамках задачи[/quote][quote=pavlo1c;24458808]
Можно переписать без использования ВТ или с их минимизацией.
[quote=pavlo1c;24458808]никак не вернет Не активных.[/quote]
Проэкспериментируй: пустая база, единственный периодический РС с единственным измерением строка и ресурсом типа булево. Делаем в РС две записи по измерению: сначала с Истина, затем - с Ложь в ресурсе. Делаем запрос
ВЫБРАТЬ Изм
ИЗ РегистрСведений.РС.СрезПоследних(, Ресурс1)
Видим в результате, что запрос нам вернул строку, хотя по этому измерению последняя запись - ложная.
Начинаем плеваться и ругаться на 1С, Lexusss, Территорию и MS SQL Server.
Потом думаем и смотрим трансляцию условий вирт таблиц на уровень SQL. Думаем еще раз, и начинаем ругаться на себя, уровень своего владения предметом, свою сообразительность и т.д. Вспоминаем с добротой о Территории, Lexusss и 1С.[quote=pavlo1c;24458808]Достаточно или нет...[/quote]
Вот это поток сознания!!! Не осилил, старею (((

pavlo 09.04.2012 12:53

(23) не осилил я ваш поток сознания :)
1. про виртуальную одну таблицу и просил пример
2. про записи из РС понятно что вернет запись с типом Ложь, так и должно работать, это значит клиента нет сейчас на тренировке, все отлично в чем проблема то?

Lexusss 09.04.2012 13:56

(23) 1. Ты врем таблицы ГотовыеМаксимальные и МаксимальныеПоКлиентам используешь в дальнейших запросах всего по одному разу. В большинстве случаев гораздо выгоднее заменить их на вложенные таблицы.
2. Исходя из ТЗ в шапке ветки "выбрать только активных клиентов" я предположил, что в запрос не должны попадать те клиенты, которые ранее Присутствовали, но теперь НЕ Присутствуют.

pavlo 10.04.2012 05:20

(24) вот и у меня ощущения, что не все поняли что мне нужно то в итоге ;)

МимохожийОднако 10.04.2012 06:13

(25)Начни с начала. 1.Опиши задачу 2.Приведи пример таблицы до запроса и таблицу в результате запроса.

pavlo 10.04.2012 07:31

(26)
Таблица Регистра Сведений:
Клиент:Присутствие
Клиент1-Истина
Клиент2-Истина
Клиент3-Ложь

Таблица Регистра Остатков (обороты) свернуто
Клиент:Услуга:Количество
Клиент1-Пилатес-2
Клиент1-Йога-3
Клиент2-Йога-1
Клиент2-Футбол-5
Клиент3-Футбол-3

Итого нужно получить тех кто из первой таблицы Истина и услугой которую чаще всего приобретает:
Клиент1-Йога
Клиент2-Футбол
(клиент3 ложь потому отсутствует в этой таблице)

roma n 10.04.2012 07:42

(27)
При таких исходных данных что?
Таблица Регистра Остатков (обороты) свернуто
Клиент:Услуга:Количество
Клиент1-Пилатес-3
Клиент1-Йога-3
Клиент2-Йога-1
Клиент2-Футбол-5
Клиент3-Футбол-3

pavlo 10.04.2012 08:05

(28) первый подходящий (как чуял спросят :) )


Текущее время: 14:46. Часовой пояс GMT +3.