Имя: Пароль:
1C
1С v8
Разминка для ума: сумма процентов в запросе
0 jcage
 
23.10.11
14:36
Имеем:

(Выбрать
10 как процент

объединить все

выбрать
20

объединить все

выбрать
30)

задача:

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

для приведенного примера коэффицент будет:
(1 + 10/100) * (1 + 20/100) * (1 + 30/100) = 1,716

вопрос, как такую чтуку провернуть в запросе? число, к которому будет применен коэффициент заранее не известно

p.s. выгрузить в таблицу и посчитать я и сам могу, интересно, можно ли такую штуку в запрос затолкать =)
1 el-gamberro
 
23.10.11
14:40
число строк в таблице процентов заранее неизвестно?
2 jcage
 
23.10.11
14:43
(1) не-а. 2 таблицы, в первой из которых значение, во второй несколько строк с процентами.
3 el-gamberro
 
23.10.11
14:57
(2) несколько это сколько?
если делать нечего можно тупо транспортировать таблицу и перемножить все ее поля.
4 Новиков
 
23.10.11
15:31
ВЫБРАТЬ
   Зап.процент,
   Зап.Коэф
ПОМЕСТИТЬ Темп
ИЗ
   (ВЫБРАТЬ
       10 КАК процент,
       1 + 10 / 100 КАК Коэф
   
   ОБЪЕДИНИТЬ ВСЕ
   
   ВЫБРАТЬ
       20,
       1 + 20 / 100
   
   ОБЪЕДИНИТЬ ВСЕ
   
   ВЫБРАТЬ
       30,
       1 + 30 / 100) КАК Зап
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   СУММА(ВЫБОР
           КОГДА Темп.процент = 10
               ТОГДА Темп.Коэф
           ИНАЧЕ 0
       КОНЕЦ) * СУММА(ВЫБОР
           КОГДА Темп.процент = 20
               ТОГДА Темп.Коэф
           ИНАЧЕ 0
       КОНЕЦ) * СУММА(ВЫБОР
           КОГДА Темп.процент = 30
               ТОГДА Темп.Коэф
           ИНАЧЕ 0
       КОНЕЦ) КАК Коэффициент
ИЗ
   Темп КАК Темп
5 МихаилМ
 
23.10.11
15:37
совместное уравнение можно решить запросом.
6 el-gamberro
 
23.10.11
16:58
(4) насколько я понял нужно получить произведение :)
например можно переменожить 1000 колонок, в пустых должна быть 1.
задача только транспортировать строки в столбцы, в пустые столбцы 1.
если есть разумное максимально возможное число строк, то ничего в этом сложного. :)
7 Новиков
 
23.10.11
17:48
(6) скопируй запрос (4) в консоль и увидишь в результате одну строку с одним полем, в котором и будет требуемое произведение :) Если я правильно понял твое непонимание )))

Кстати, аналогично можно было результата и вот так:

ВЫБРАТЬ
   Зап.процент,
   Зап.Коэф
ПОМЕСТИТЬ Темп
ИЗ
   (ВЫБРАТЬ
       10 КАК процент,
       1 + 10 / 100 КАК Коэф
   
   ОБЪЕДИНИТЬ ВСЕ
   
   ВЫБРАТЬ
       20,
       1 + 20 / 100
   
   ОБЪЕДИНИТЬ ВСЕ
   
   ВЫБРАТЬ
       30,
       1 + 30 / 100) КАК Зап
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   МАКСИМУМ(ВЫБОР
           КОГДА Темп.процент = 10
               ТОГДА Темп.Коэф
           ИНАЧЕ NULL
       КОНЕЦ) * МАКСИМУМ(ВЫБОР
           КОГДА Темп.процент = 20
               ТОГДА Темп.Коэф
           ИНАЧЕ NULL
       КОНЕЦ) * МАКСИМУМ(ВЫБОР
           КОГДА Темп.процент = 30
               ТОГДА Темп.Коэф
           ИНАЧЕ NULL
       КОНЕЦ) КАК Поле1
ИЗ
   Темп КАК Темп

Повнимательнее почитав (2) (2 таблицы, в первой из которых значение, во второй несколько строк с процентами) мне кажется, что автор хотел все таки, не то, что он описал в (0). Спасет автора ранжирование уникальных пар значение-процент + запросы, которые я уже привел с небольшой модификацией. Но с учетом реализации языка запроса в 1С, задача вроде бьется на:
1. само ранжирование
2. транспонирование результирующей выборки.

Если проценты как-то там кратны предположим 10, 5 или как-то еще - через конкатенацию можно получить нужный запрос. Если нет и количество различных процентов велико, то (видимо) смысла получать все это в запросе уже нет никакого. К Владу Кадони ходить не нужно будет, чтобы понять - что проще все сделать через тупое ТЗ.

В любом случае - автору - удачи!
8 ILM
 
гуру
23.10.11
19:06
(0) Я так понял, что автор решает проблему расчета цены или другого свойства по различным свойствам товара?
Как вариант решать задачу "запросом в цикле ))". Цикл по строкам выборки "процентов", передавать параметром в другой запрос "процент" и далее перемножать результат "Темп" сам на себя.
9 jcage
 
23.10.11
19:12
(3) транспортация нарушает условие не кодирования )) идея именно в том, что бы все в запрос затолкать. не хочется прерывать цикл пакетных запросов, вручную обрабатывать и опять заталкивать в пакет )

(4) Не получиться, т.к. я не знаю, сколько строк в таблице. то что ты написал реализуемо, если запрос собирать динамически в коде. из предыдущего обзаца понятно, что я как раз хочу избежать предварительной обработки всех строк, по которым надо посчитать произведение.

(8) уважаемый, заранее извини, если тебе покажется что я грублю. но, знающие меня люди понимают, что я спрашиваю не задачу ламерского уровня. поэтому прошу твои догадки оставить при себе. конкретно в моем случае есть тур с базовыми ценами, к которому бывает около 10-20 спецпредложений как в процентах, так и в фиксированных скидках и доплатах с различными условиями и условиями на комбинацию этих самых спецпредложений. т.к. мой запрос расчета стоимости занимает 4 экрана, то я не хочу посередине запроса выгружать результат в ТЗ, обрабатывать ее и окончательно досчитывать запросом. соответственно мне нужно решить задачу, приведнную в (0). это чисто программерско-философский вопрос и не имеет вопроса к конкретной реализации, идею которой привел ты - у меня и так все прекрасно работает с промежуточной обработкой. Если есть идеи по поводу (0) прошу высказываться :-)
10 ILM
 
гуру
23.10.11
19:29
(9) Грубо не кажется, пытаюсь помочь.

Если точно так как в описано в (0), то запросом в 1С это невозможно.
В Оракл, это делается созданием собственной агрегатной функции МНОЖСУММА(): перемножающей суммированные значения в запросе.
У Вас два пути:
1) все возможные варианты записать в запрос, не разрешая потом добавлять новые алгоритмы расчета
2) создать гибкий алгоритм, но уже без запроса.
11 Новиков
 
23.10.11
19:33
(9) >>из предыдущего обзаца понятно, что я как раз хочу избежать предварительной обработки всех строк, по которым надо посчитать произведение.

В рамках языка запросов 1С твой философский вопрос ответ имеет печальный: НИКАК то что ты хочешь там не сделать.
12 Ненавижу 1С
 
гуру
23.10.11
19:56
помещать не проценты, а логарифмы коэффициентов, суммировать в результате запросе, брать потом экспоненту
13 ILM
 
гуру
23.10.11
20:07
(12) Круто)))
Я сначала про ряды Фурье подумал, может нужно Пи поделить.
14 Ненавижу 1С
 
гуру
23.10.11
20:08
(13) это такой стёб?
15 ILM
 
гуру
23.10.11
20:21
(14) Ну чуть-чуть))) Хотя про ряды Фурье чистая правда: 1/2 + 1/3 + 1/4 и т.д. А потом уже увидел что умножать нужно.
16 el-gamberro
 
23.10.11
20:37
(9) затолкай транспорирование в запрос. какие проблемы?
17 jcage
 
23.10.11
21:20
(16) поподробнее пжл) не умею я такого штатными средстами)
18 Lama12
 
23.10.11
21:52
(0)А может лучше без запроса?
Про точность в запросах слышал?
Точность вычислений устроит?
19 jcage
 
23.10.11
22:14
(18) без запроса уже работает. вопрос философский.. точность устраивает.. по поводу научить меня ньансам читай (9) в разделе к ответу (8)
20 el-gamberro
 
24.10.11
13:56
(17)
row_id  value
1       20
2       10
3       30

ВЫБРАТЬ ВЫБОР КОГДА роу_ид = 1 ТОГДА value ИНАЧЕ 100 КОНЕЦ КАК ПерваяКолонка,
....
ВЫБОР КОГДА роу_ид = 100 ТОГДА value ИНАЧЕ 100 КОНЕЦ КАК СотаяКолонка
21 el-gamberro
 
24.10.11
13:58
+(20) Точнее там 0 должен быть. а чтобы свернуть таблицу использовать сумму
22 jcage
 
24.10.11
18:16
(20) опять же это не для неограниченного числа строк.

я решил задачу, но с ограничением точности. Жду пока кто-то придумает лучше)))

x1 = первый процент в тз, заведомо меньше 1-цы, т.к. уже разделен на 100. Допустим 0.1
x2 = второй процент в тз, заведомо меньше 1-цы, т.к. уже разделен на 100. Допустим 0.2
...
xN = n-ый процент в тз, заведомо меньше 1-цы, т.к. уже разделен на 100. Допустим 0.n

коэффициент в первой строке, умножив на которое неизвестное получим искомую сумму с процентами (1 + x1), во второй (1 + x2) и т.д.

(1+x1)(1+x2) = 1 + x1 + x2 + x1x2;
(1+x1)(1+x2)(1+x3) = 1 + x1 + x2 + x3 + x1x2 + x2x3 + x1x3 + x1x2x3;

очевидно, что есть постоянная часть 1, СУММА(X), а также СУММА(Табл1.Процент*Табл2.Процент), при соединении таблиц по Табл1.НомерСтроки < Табл2.НомерСтроки

так же очевидно, что x1*x2...*xn стремиться к нулю, т.к. x < 1.

Таким образом выбрав соединение 4-ех таблиц по описанным принципам можно добиться точности вполне достаточной для работы с денежными показателями до 10 000 рублей. Что в моем случае вполне приемлимо.

можно соединять 17 таблиц - получиться точность, удовлетворяющая принятый в 1С тип для денег (15,2).

решение не идеальное, но вполне математически доказанное.

кто лучше? ;)
23 ILM
 
гуру
25.10.11
20:15
(22) Кстати полезная штука, я сейчас по ТОС что-то подобное считаю с вероятностями отклонений от статистической устойчивости процесса, для оценки выполнимости бюджетов и планов.

Но оставил пока запросы в цикле.
Кстати нужно вышку вспомнить по пределам, там интеграл наверное будет... за 2о лет уже многое забылось, нужно полистать Выгодского...
24 Rovan
 
гуру
25.10.11
20:43
(0) а так нельзя ?

((10/100) + (20/100) + (30/100)) / 3 = 0.2
25 jcage
 
27.10.11
09:55
(24) x * (1 + 10/100) * (1 + 20/100) * (1 + 30/100) = 1,716 * x

нельзя.
Ошибка? Это не ошибка, это системная функция.