Вход | Регистрация
 

Раздумья над запросом

Раздумья над запросом
Я
   Начинающий Восьмерочн
 
03.09.08 - 17:22
Появилась задача, выбрать пять последних продаж(количество товара) в разрезе товаров и контрагентов, то есть для каждого контрагента(входящего в некий список) получить 5(или более) последних продаж товара(входящих в некий список).
Как без запроса это сделать понятно, но интересно возможно ли создать такой запрос чтобы он сам все выбрал ?
Конфв УТП для украины, хотя это и не важно наверное.В общем хочу услышать мнения возможно решить такую задачу одним запросом или нет.
   Elysee
 
1 - 03.09.08 - 17:23
В наше время запрос может вытащить все, основная сложность его составить
   Лис в курятнике
 
2 - 03.09.08 - 17:23
можно
   Начинающий Восьмерочн
 
3 - 03.09.08 - 17:26
Собственно как бы и вопрос как его правильно составить, я как не пробовал составить он получается неоптимальный, думаю очень долго будет работать, может кто подскажет основную мысль как его составить ?
   Elysee
 
4 - 03.09.08 - 17:30
Хорошо было бы взглянуть на неоптимальный запрос :)
   Начинающий Восьмерочн
 
5 - 03.09.08 - 17:34
Ну я пока заготовки всякие делал, пришел к выводу что конструкция выбрать первые 5 не катит, потому как выберутся первые 5 документов или товаров, с вложенным запросом тоже непонятки, он будет лопатить типа всю базу , а это не выход, вот сижу и думаю ищи еще варианты, а кажется что они есть.
   zag2art
 
6 - 03.09.08 - 17:34
Интересно, а как получить ПЕРВЫЕ 5 для каждого контрагента??? Туплю или нельзя???
   Начинающий Восьмерочн
 
7 - 03.09.08 - 17:41
Для каждого в том то и дело что нельзя, по крайней мере я не знаю как.
   Rabajaba
 
8 - 03.09.08 - 17:45
Можно. Для начала надо как-то отсортировать и пронумеровать строки. Для документов вообще песня - есть "НомерСтроки"
Пример:

ВЫБРАТЬ
   ОприходованиеБракаТовары.Ссылка,
   ОприходованиеБракаТовары.НомерСтроки
ИЗ
    Документ.ОприходованиеБрака.Товары КАК ОприходованиеБракаТовары
        ЛЕВОЕ СОЕДИНЕНИЕ Документ.ОприходованиеБрака.Товары КАК ОприходованиеБракаТовары1
        ПО ОприходованиеБракаТовары.Ссылка = ОприходованиеБракаТовары1.Ссылка
ГДЕ
    ОприходованиеБракаТовары.НомерСтроки < ОприходованиеБракаТовары1.НомерСтроки

СГРУППИРОВАТЬ ПО
    ОприходованиеБракаТовары.Ссылка,
    ОприходованиеБракаТовары.НомерСтроки
ИМЕЮЩИЕ
    ОприходованиеБракаТовары.НомерСтроки < 5
   Rabajaba
 
9 - 03.09.08 - 17:47
И так что мы делаем.
Делаем выборку из табличной части документа и той же табличной части с левым соединением по какому-то уникальному идентификатору(в данном случае .Ссылка)
После чего пишем условие ГДЕ, чтобы отсортировать строки.
После чего накладываем группировку по уникальному идентификатору( опять же .Ссылка) и ставим критерий отбора на 5 строк ИМЕЮЩИЕ
    ОприходованиеБракаТовары.НомерСтроки < 5
   Krom
 
10 - 03.09.08 - 17:53
Дружище, а ты этот запрос где-то используешь? какой то он странный!
   Начинающий Восьмерочн
 
11 - 03.09.08 - 17:55
ну вот хоть какойто вариант уже появился :-))
   Rabajaba
 
12 - 03.09.08 - 17:55
Правда, ошибся я малясь ... давно подобного не писал :)
Вот полезнейшая ссылочка:
http://www.sql.ru/faq/faq_topic.aspx?fid=126 (в случае 1С можно использовать только вариант №1 и №2)
Что получим на выходе - пронумерованные результаты запроса, наложив свои группировки можно пронумеровать строки внутри группировок после чего поставить критерий на номер строки.
   Начинающий Восьмерочн
 
13 - 03.09.08 - 18:03
это все же не совсем то, поскольку надо контрагентов привязать и вытащить еще и количество по этим товарам, то есть нумеровать надо сделки (документы) а не строки товаров, ну мысль инетересная в примере , хотя ща не осилю наверное пока такой подход
   Rabajaba
 
14 - 03.09.08 - 18:10
Советую начать с малого.
Пронумеруйте документы в разрезе группировки по контрагентам, после чего необходимо убрать лишние (например, начиная с шестого и выше).
После чего у Вас будет выборка нужных Вам документов по необходимым контрагентам.
А далее присоединить табличную часть уже выбранных документов не составит труда.
   Вопрос_по_Бух
 
15 - 03.09.08 - 18:38
o_O а что регистры уже отменили ?
   Вопрос_по_Бух
 
16 - 03.09.08 - 18:39
(8) ога  посчитаешь таким запросом все помеченные на удаление документы ...
   Rabajaba
 
17 - 03.09.08 - 18:41
Придираться только не надо, да? Глупо как-то выглядит.
   Вопрос_по_Бух
 
18 - 03.09.08 - 18:42
(17)что именно глупо ?
   Zapal
 
19 - 03.09.08 - 18:48
Rabajaba всё сказал, единственно что можно добавить
а) тормозить такой запрос должен страшно
б) автору такое не осилить, лучше забей 8)
   Rabajaba
 
20 - 03.09.08 - 18:51
Придирки на ровном месте.
Понятие "продажи" у всех разное. Это могут быть и не проведенные документы.
А добавить проверку на помеченные на удаление думаю не составит проблем ни у кого.
Плюс ко всему задача ведь переросла в русло "последние 5 по группировке" посему считаю, что здесь важен метод реализации, а не адаптация к условиям первого поста.
Далее: "А далее присоединить табличную часть уже выбранных документов не составит труда" здесь намеренно указана фраза "табличную часть", т.к. она может хранится в нескольких регистрах.
Выборка документов из "ДокументСсылка" отрабатывает всегда быстрее, чем группировка по документу в регистре.
   Вопрос_по_Бух
 
21 - 03.09.08 - 18:51
(0) анализируй таблицу регистра накопления Продажи.Обороты
   Rabajaba
 
22 - 03.09.08 - 18:54
Насчет тормозов:
Нумерация процесс действительно тяжелый, но при правильных объемах выборки (период, организация, контрагент и тп) довольно не плохо отрабатывает. Плюс правильное конструирование запрос даст довольно оптимизированный вариант.
Конечно если нумеровать 50к строк это будет медленно и если не корректную вложенность использовать ещё медленнее.
С полгода назад писал подобное - результатами производительности был доволен.
   Вопрос_по_Бух
 
23 - 03.09.08 - 18:54
(19) +1
   Zapal
 
24 - 03.09.08 - 18:57
(22) не забывай, что нумерация не одна, а по каждому контрагенту

можно попробовать использовать нумерацию в компоновке данных - если по ней работают отборы тогда всё просто
   Вопрос_по_Бух
 
25 - 03.09.08 - 18:57
(22) документ реализации имеет 22 позиции.... сколько  это по  вашему количеств продаж ?
   Начинающий Восьмерочн
 
26 - 03.09.08 - 19:06
в общем лучше от запроса наверное отказатся потому как если 20 клиентов по 5 документов и товаров 1000 например, хотя ради прикола замеряю, что будет быстрее выборка или запрос
   zag2art
 
27 - 04.09.08 - 09:50
Вот запрос нумерует номенклатуру...
[1с]
ВЫБРАТЬ
   Номенклатура.Ссылка КАК Номенклатура,
   КОЛИЧЕСТВО(Номенклатура_1.Ссылка) КАК Номер
ИЗ
   Справочник.Номенклатура КАК Номенклатура
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура_1
       ПО Номенклатура.Наименование >= Номенклатура_1.Наименование


СГРУППИРОВАТЬ ПО
   Номенклатура.Ссылка
[/1с]
   zag2art
 
28 - 04.09.08 - 09:50
Вот запрос нумерует номенклатуру в рамках группировки по родителю:
[1с]
ВЫБРАТЬ
   Номенклатура.Ссылка КАК Номенклатура,
   Номенклатура.Родитель КАК Родитель,
   КОЛИЧЕСТВО(Номенклатура_1.Ссылка) КАК Номер
ИЗ
   Справочник.Номенклатура КАК Номенклатура
       ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура_1
       ПО Номенклатура.Наименование >= Номенклатура_1.Наименование
           И Номенклатура.Родитель = Номенклатура_1.Родитель

СГРУППИРОВАТЬ ПО
   Номенклатура.Родитель,
   Номенклатура.Ссылка
[/1с]
   zag2art
 
29 - 04.09.08 - 09:52
А вот запрос выбирающий 5 позиций номенклатуры в рамках группировки по родителю:
[1с]
ВЫБРАТЬ
   ВложенныйЗапрос.Родитель КАК Родитель,
   ВложенныйЗапрос.Номенклатура КАК Номенклатура,
   ВложенныйЗапрос.Номер КАК Номер
ИЗ
   (ВЫБРАТЬ
       Номенклатура.Ссылка КАК Номенклатура,
       Номенклатура.Родитель КАК Родитель,
       КОЛИЧЕСТВО(Номенклатура_1.Ссылка) КАК Номер
   ИЗ
       Справочник.Номенклатура КАК Номенклатура
           ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура_1
           ПО Номенклатура.Наименование >= Номенклатура_1.Наименование
               И Номенклатура.Родитель = Номенклатура_1.Родитель
   
   СГРУППИРОВАТЬ ПО
       Номенклатура.Родитель,
       Номенклатура.Ссылка) КАК ВложенныйЗапрос
ГДЕ
   ВложенныйЗапрос.Номер <= 5

УПОРЯДОЧИТЬ ПО
   Родитель,
   Номер
[/1с]
Да.. Во всех запросах номанклатура сортируется по возрастанию по полю Наименование, но можно естественно и по любому другому полю
   zag2art
 
30 - 04.09.08 - 09:54
Могу кстати статейку для базы знаний написать - или такая информация уже была???
 
 Рекламное место пустует
   Rabajaba
 
31 - 04.09.08 - 10:13
Думаю для статьи метода нумеровки запроса будет маловато :)
Автор - давай ещё задачу!
   zag2art
 
32 - 04.09.08 - 10:19
А почему бы и нет. Мне кажется частенько нужно.
   Rabajaba
 
33 - 04.09.08 - 10:23
Вам виднее. Просьба в статье указать ссылочку на FAQ по T-SQL на sql.ru - может кому ещё чего интересного понадобится.
   zag2art
 
34 - 04.09.08 - 10:31
(33)Хорошо, если олл решит, что статья вообще нужна.
   Начинающий Восьмерочн
 
35 - 04.09.08 - 16:17
данные примеры про справочник, а вот если бы пример документов по товару, бьюсь ни фига не выходит
   Начинающий Восьмерочн
 
36 - 04.09.08 - 16:22
хотя в (29) я сразу не заметил кажись стоящий кусочек, ща поброю с ним поэкспериментировать
   zag2art
 
37 - 04.09.08 - 16:32
   zag2art
 
38 - 04.09.08 - 16:33
(36) В ссылке из (37), в конце, есть пример по документам
   Rabajaba
 
39 - 04.09.08 - 16:35
Хороша статья. Доступно написано :)
   zag2art
 
40 - 04.09.08 - 16:36
(39) Стараемся :)
   Начинающий Восьмерочн
 
41 - 04.09.08 - 22:14
(40) да суперски, теперь попробую разобратся и добавить еще товары и тогда задача будет полностью решена, про нумерацию строк в запросе как то и не догадывался, теперя менеджеры таким витиеватым запросом смогут развернуть произвольное количество продаж любого товара и проанализировать когда и сколько брал.
   дущ
 
42 - 04.09.08 - 23:34
(27) помойму хитро, но не оптимально. А если у нас 10000 позиций номенклатуры. Получается что запрос будет группировать почти 100000000 строк? Этож сколько он будет делаться?
   КонецЦикла
 
43 - 05.09.08 - 04:28
В порядке бреда предлагаю ультравариант вбок :)
Выполнять в QA
Пример для трех последних продаж
Можно и не вбок... но вы же хотели без циклов и курсоров...

if object_id('tempdb..#doc') is not null drop table #doc
create table #doc (kontr int, tovar int, dat datetime)

insert into #doc values (1, 1, '2008-01-08')
insert into #doc values (1, 1, '2008-02-08')
insert into #doc values (1, 1, '2008-03-08')
insert into #doc values (1, 1, '2008-10-08')
insert into #doc values (1, 2, '2008-04-08')

insert into #doc values (2, 1, '2008-05-08')
insert into #doc values (2, 2, '2008-06-08')
insert into #doc values (2, 2, '2008-07-08')

insert into #doc values (3, 1, '2008-08-08')
insert into #doc values (3, 1, '2008-09-08')
insert into #doc values (3, 2, '2008-10-08')
insert into #doc values (3, 2, '2008-11-08')

if object_id('tempdb..#kontr') is not null drop table #kontr
if object_id('tempdb..#tovar') is not null drop table #tovar

select distinct kontr into #kontr from #doc
select distinct tovar into #tovar from #doc

select k.kontr, t.tovar, d.dat последняя, d1.dat предпоследняя, d2.dat предпредпоследняя
from #kontr k
cross join #tovar t
left join #doc d on k.kontr = d.kontr and t.tovar = d.tovar and d.dat = (select max(dat) from #doc where kontr = k.kontr and tovar = t.tovar)
left join #doc d1 on k.kontr = d1.kontr and t.tovar = d1.tovar and d1.dat = (select max(dat) from #doc where kontr = k.kontr and tovar = t.tovar and dat < d.dat)
left join #doc d2 on k.kontr = d2.kontr and t.tovar = d2.tovar and d2.dat = (select max(dat) from #doc where kontr = k.kontr and tovar = t.tovar and dat < d1.dat)
   zag2art
 
44 - 05.09.08 - 09:12
(43) А теперь то же самое, только в v8.
   lamort
 
45 - 05.09.08 - 10:00
(37) Может ещё стаью по генерации последовательности чисел и последовательности дат при помощи языка запросов написать?
   zag2art
 
46 - 05.09.08 - 10:14
(45) Думаю, было-б здорово
   lamort
 
47 - 05.09.08 - 10:17
(46) В обед попробую написать с практическим примером.
   Rabajaba
 
48 - 05.09.08 - 10:21
Что-то я не понял, как переменные t и k попали в подзапросы?

select k.kontr, t.tovar, d.dat последняя, d1.dat предпоследняя, d2.dat предпредпоследняя
from #kontr k
cross join #tovar t
left join #doc d on k.kontr = d.kontr and t.tovar = d.tovar and d.dat = (select max(dat) from #doc where kontr = k.kontr and tovar = t.tovar)
left join #doc d1 on k.kontr = d1.kontr and t.tovar = d1.tovar and d1.dat = (select max(dat) from #doc where kontr = k.kontr and tovar = t.tovar and dat < d.dat)
left join #doc d2 on k.kontr = d2.kontr and t.tovar = d2.tovar and d2.dat = (select max(dat) from #doc where kontr = k.kontr and tovar = t.tovar and dat < d1.dat)
   rsv
 
49 - 05.09.08 - 10:28
select top 5 *  from DH15777 order by IDDOC  DESC
   rsv
 
50 - 05.09.08 - 10:29
+(49) В 8-ке есть аналог DESC ??
   Rabajaba
 
51 - 05.09.08 - 10:31
Убыв
   rsv
 
52 - 05.09.08 - 10:35
+(51) Этож хорошо :)
   rsv
 
53 - 05.09.08 - 10:39
(51) Вот определяйся с полем по котрому будешь сортировать (Дата+время наверное ???) и в путь :)
   rsv
 
54 - 05.09.08 - 10:40
+(53) А после where  полет фантазии на фильтры
   zag2art
 
55 - 05.09.08 - 10:41
Жду, потирая руки, окончательного варианта для v8
   rsv
 
56 - 05.09.08 - 10:46
+(53) А задействовав механизм временных таблиц 8 ки,oтсортированную таблицу грузим во времянку. И к времянке уже select top 5 from времянка. К времянке уже можно после TOP хоть 100,хоть 200. Главное данные уже отсортированы и время на сортировку тратится не будет. Должно взлетеь :)
   zag2art
 
57 - 05.09.08 - 12:34
Ну как там с запросом-то???
   lamort
 
58 - 05.09.08 - 13:42
(45) Книга знаний: v8: Генерация числовой последовательности и последовательности дат при помощи языка запросов. - Статья по  генерации последовательности чисел и дат с с помощью запросов.
   zag2art
 
59 - 05.09.08 - 13:57
Зацени:
[1с]
ВЫБРАТЬ
0 КАК А ПОМЕСТИТЬ Числа
ОБЪЕДИНИТЬ ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВЫБРАТЬ 9;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Числа1.А*100 + Числа2.А*10 + Числа3.А
ИЗ
    Числа КАК Числа1,
    Числа КАК Числа2,
    Числа КАК Числа3
[/1с]
Без внутренних соединений и без ПО (ИСТИНА)
   zag2art
 
60 - 05.09.08 - 14:04
Мне кажется так для восприятия проще, да и расширять элементарно.
 
 Рекламное место пустует
   zag2art
 
61 - 05.09.08 - 14:11
Даже вот так:
ВЫБРАТЬ
0 КАК А ПОМЕСТИТЬ Числа
ОБЪЕДИНИТЬ ВЫБРАТЬ 1
ОБЪЕДИНИТЬ ВЫБРАТЬ 2
ОБЪЕДИНИТЬ ВЫБРАТЬ 3
ОБЪЕДИНИТЬ ВЫБРАТЬ 4
ОБЪЕДИНИТЬ ВЫБРАТЬ 5
ОБЪЕДИНИТЬ ВЫБРАТЬ 6
ОБЪЕДИНИТЬ ВЫБРАТЬ 7
ОБЪЕДИНИТЬ ВЫБРАТЬ 8
ОБЪЕДИНИТЬ ВЫБРАТЬ 9;
 ////////////////////////////////////////////////////////////////////////////////  
ВЫБРАТЬ
Числа3.А*100 + Числа2.А*10 + Числа1.А КАК Число
ИЗ
     Числа КАК Числа3,
     Числа КАК Числа2,
     Числа КАК Числа1
   zag2art
 
62 - 05.09.08 - 14:16
(58) Для читабельности, я бы разнес генерацию чисел, дат и основной запрос в пакете запросов.
   lamort
 
63 - 05.09.08 - 14:31
(62) Примеры писались "на коленке". Я эти приемы использовал только в SQL, только сегодня столкнулся с реальной задачей в 1С, где это нужно. Ну а по содержанию как?
   zag2art
 
64 - 05.09.08 - 14:37
Атлична. Мне понравилось
   lamort
 
65 - 05.09.08 - 14:39
(64) Спасибо, на выходных постараюсь подредактирвать, сделать более читабельным. А счас работать пора, начальство ругуется :)
   zag2art
 
66 - 05.09.08 - 14:40
(63) Да, последний запрос - уж больно большой. Это плохо для обучения.


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Ветка сдана в архив. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.