powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
19 сообщений из 19, страница 1 из 1
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40079690
Ann2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Уважаемые знатоки,
Помогите пожалуйста может с идееи а может есть решение...

Имеются такие данные:
расписание студента в 1 день может иметь от 1 до 11 классов, разные вариации у разных студентов.
каждый день студент может присутствовать или отсутствовать по ряду причин,
например на одном классе присутствует персонально (П),
на другом - онлаин (О)
и также может отсутствовать по еще 4 причинам, например "без уважительнои", "с уважительнои" и еще парочку причин.
Все возможные причины: ЕХ, Х, П, ПР, М, О
они могут случиться в один день все вместе или только некоторые, но как минимум одна причина всегда есть.
Мне надо посчитать
на каждого студента,
на каждыи день
какая часть дня падает на какую причину до тысячнои.
Я делю для каждои причины кол-во классов на общее кол-во классов в день для студента,
чтоб наити какая часть дня относиться к причине и округляю до 3
Все получается хорошо кроме одного:

ФАМИЛИЯ ДАТА ЕХ Х П ПР О
Петров 01/01/2021 0.333 0.000 0.333 0.000 0.333

Это пример когда у студента было 3 причины по 2 класса на каждую и всего 6 классов в расписании, т.е. 2/6 для ЕХ, 2/6 для П и 2/6 для О
Могут быть разные варианты 1/7, 1/9....
Проблема: если сейчас суммировать все части, то получу не 1.000 а 0.999. Непорядок.
Есть ли волшебная функция, которая бы мне поделила бы все так, чтоб в итоге сумма была бы 1.000?
За любые подсказки спасибо.
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40079692
Фотография Vadim Lejnin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
2.
3.
4.
5.
SQL> select 1/3 + 1/3 + 1/3 as n from dual;

	 N
----------
	 1
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40079695
Фотография Vadim Lejnin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ann2,
А вообще, прочитай про как хранятся числа, ошибку округления ( на форуме не раз разбирали)
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SQL> select to_char(1.0/3.0 + 1.0/3.0 + 1.0/3.0,'09D9999999999999999999') as n from dual
SQL> /

N
-----------------------
 01.0000000000000000000


SQL> select to_char(1.0/3.0 + 1.0/3.0 + 1.0/3.0,'09D999999999999999999999999999999999999999999999999999999999999') as n from dual
SQL> /

N
----------------------------------------------------------------
 00.999999999999999999999999999999999999999900000000000000000000
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40079702
Ann2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот так я считаю,
Вот так я считаю,
здесь получаю все поделенное до бесконечности.


DECODE(NVL(state_att_code,'NULL'),'EX', 1,0)/COUNT (per.period_number) OVER (PARTITION BY TO_CHAR(sec.schoolid)||TO_CHAR(cc.studentid)||TO_CHAR(date_value,'YYYYMMDD')) TOTAL_EX,
DECODE(NVL(state_att_code,'NULL'),'UX', 1,0)/COUNT (per.period_number) OVER (PARTITION BY TO_CHAR(sec.schoolid)||TO_CHAR(cc.studentid)||TO_CHAR(date_value,'YYYYMMDD')) TOTAL_UX,
DECODE(NVL(state_att_code,'NULL'),'MH', 1,0)/COUNT (per.period_number) OVER (PARTITION BY TO_CHAR(sec.schoolid)||TO_CHAR(cc.studentid)||TO_CHAR(date_value,'YYYYMMDD')) TOTAL_MH,
DECODE(NVL(state_att_code,'NULL'),'HP', 1,0)/COUNT (per.period_number) OVER (PARTITION BY TO_CHAR(sec.schoolid)||TO_CHAR(cc.studentid)||TO_CHAR(date_value,'YYYYMMDD')) TOTAL_HP,
DECODE(NVL(state_att_code,'NULL'),'EL', 1,0)/COUNT (per.period_number) OVER (PARTITION BY TO_CHAR(sec.schoolid)||TO_CHAR(cc.studentid)||TO_CHAR(date_value,'YYYYMMDD')) TOTAL_EL,


В следующем куске кода округляю и агрегирую по месяцу, т.е. из 0.3333333333333333333333333333333333333333333333333........................
0.333
в итоге на год у меня не хватает нескольких малюсеньких фракции или наоборот - лишние

select id, month,round(sum(total_ex),3), round(sum(total_ux),3)...
from tab_above
group by id, month

Мне непонятно как использовать формат to_char в данном случае
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40079715
Фотография Vadim Lejnin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ann2
Вот так я считаю,
Вот так я считаю,
здесь получаю все поделенное до бесконечности.

Код: plsql
1.
2.
3.
4.
5.
DECODE(NVL(state_att_code,'NULL'),'EX', 1,0)/COUNT (per.period_number) OVER (PARTITION BY TO_CHAR(sec.schoolid)||TO_CHAR(cc.studentid)||TO_CHAR(date_value,'YYYYMMDD')) TOTAL_EX,
DECODE(NVL(state_att_code,'NULL'),'UX', 1,0)/COUNT (per.period_number) OVER (PARTITION BY TO_CHAR(sec.schoolid)||TO_CHAR(cc.studentid)||TO_CHAR(date_value,'YYYYMMDD')) TOTAL_UX,
DECODE(NVL(state_att_code,'NULL'),'MH', 1,0)/COUNT (per.period_number) OVER (PARTITION BY TO_CHAR(sec.schoolid)||TO_CHAR(cc.studentid)||TO_CHAR(date_value,'YYYYMMDD')) TOTAL_MH,
DECODE(NVL(state_att_code,'NULL'),'HP', 1,0)/COUNT (per.period_number) OVER (PARTITION BY TO_CHAR(sec.schoolid)||TO_CHAR(cc.studentid)||TO_CHAR(date_value,'YYYYMMDD')) TOTAL_HP,
DECODE(NVL(state_att_code,'NULL'),'EL', 1,0)/COUNT (per.period_number) OVER (PARTITION BY TO_CHAR(sec.schoolid)||TO_CHAR(cc.studentid)||TO_CHAR(date_value,'YYYYMMDD')) TOTAL_EL,


В следующем куске кода округляю и агрегирую по месяцу, т.е. из 0.3333333333333333333333333333333333333333333333333........................
0.333
в итоге на год у меня не хватает нескольких малюсеньких фракции или наоборот - лишние

Код: plsql
1.
2.
3.
select id, month,round(sum(total_ex),3), round(sum(total_ux),3)...
from tab_above
group by id, month



Мне непонятно как использовать формат to_char в данном случае


to_char - это просто формат отображения
Само число, формата не имеет
Вам достаточно выбрать для хранения тип number с нужной точностью

Явно указываем с какой точностью использовать результат операции
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
SQL> set pages 40
SQL> select
to_char(cast (1.0 as float(126)) / cast (3.0 as float(126))
  ,'09D999999999999999999999999999999999999999999999999999999999999') as n1
,to_char(cast (1.0 / 3.0 as float(126))
  ,'09D999999999999999999999999999999999999999999999999999999999999') as n2
,to_char(
  cast (1.0 as float(126)) / cast (3.0 as float(126)) +
  cast (1.0 as float(126)) / cast (3.0 as float(126)) +
  cast (1.0 as float(126)) / cast (3.0 as float(126))
,'09D999999999999999999999999999999999999999999999999999999999999') as s1
,to_char(
        cast (1.0 / 3.0 as float(126)) +
        cast (1.0 / 3.0 as float(126)) +
        cast (1.0 / 3.0 as float(126))
  ,'09D999999999999999999999999999999999999999999999999999999999999') as s2
,to_char(
        cast (1.0 / 3.0 as float(126)) +
        cast (1.0 / 3.0 as float(126)) +
        cast (1.0 / 3.0 as float(126))
  ,'09D9999999999999999999999999999999999999') as s3
from dual
/


N11
----------------------------------------------------------------
N2
----------------------------------------------------------------
S1
----------------------------------------------------------------
S2
----------------------------------------------------------------
S3
-----------------------------------------
 00.333333333333333333333333333333333333333300000000000000000000
 00.333333333333333333333333333333333333330000000000000000000000
 00.999999999999999999999999999999999999999900000000000000000000
 00.999999999999999999999999999999999999990000000000000000000000
 01.0000000000000000000000000000000000000




p.s. Используйте теги для оформления кода
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40080159
Алекссс
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ann2,
1/3 +
1/3 +
1 - 1/3 - 1/3
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40080180
Фотография Vadim Lejnin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алекссс,
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
SQL> edi t
var fmt1 varchar2(100)
var fmt2 varchar2(100)

exec :fmt1 := '09D999999999999999999999999999999999999999999999999999999999999'
exec :fmt2 := '09D999999999999999999999999999999999999999'

set head off feed off

with t as (
select
        cast (1.0 as float(126)) / cast (3.0 as float(126)) as f1
        , cast (1.0 / 3.0 as float(126)) as f2
from dual
)
select
to_char(f1 , :fmt1 )
,to_char(f2, :fmt1 )
,to_char(f1 + f1 + f1, :fmt1 )
,to_char(f2 + f2 + f2, :fmt1 )
,to_char(f1 + f1 + 1.0 - f1 - f1, :fmt1 )
,to_char(f1 + f1 + f1, :fmt2 )
,to_char(f2 + f2 + f2, :fmt2 )
from t
/

SQL> @ t

 00.333333333333333333333333333333333333333300000000000000000000
 00.333333333333333333333333333333333333330000000000000000000000
 00.999999999999999999999999999999999999999900000000000000000000
 00.999999999999999999999999999999999999990000000000000000000000
 01.000000000000000000000000000000000000010000000000000000000000
 01.000000000000000000000000000000000000000
 00.999999999999999999999999999999999999990
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40082232
Ann2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vadim Lejnin,

Thank you so much!
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40082238
Правильный Вася
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ann2
чтоб наити какая часть дня относиться к причине и округляю до 3

Нужно понимать разницу между данными для показа и данными для расчётов.
До 3 знаков имеет смысл округлять при показе. А вот для расчётов ничего округлять не надо.
Это как этикетка товара и его штрих-код. Говорят об одном, но выглядят по-разному.
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40082314
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Правильный Вася

До 3 знаков имеет смысл округлять при показе. А вот для расчётов ничего округлять не надо.


зависит от задачи
если не округлять, то "итого" будет звать

.....
stax
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40082316
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Правильный Вася
До 3 знаков имеет смысл округлять при показе. А вот для расчётов ничего округлять не надо.

В области финансов и налогов данный тезис не особо применим.
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40082335
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
нужно принять правило сброса дельты на какой-то элемент (или группу элементов)
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40082358
Фотография orawish
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ann2,
andreymx
нужно принять правило сброса дельты на какой-то элемент (или группу элементов)

вот именно. каждую составляющую округляйте (вниз) до рубля (или грубее), а получившуюся в итоге дельту
отправляйте, хотя бы и , детям африки
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40082450
Правильный Вася
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous
Правильный Вася
До 3 знаков имеет смысл округлять при показе. А вот для расчётов ничего округлять не надо.

В области финансов и налогов данный тезис не особо применим.

Ложное мнение.
Вот типичный пример. Стоимость кубометра газа 5.56151 руб. Если вы перед расчетами (финансовыми) округлите его до копеек (5.56), то при оплате простым потребителем 10 кубов (55.60) поставщик потеряет 1.51 копейки на "утруску/усушку". Пренебрежимо мало, казалось бы. А если таких потребителей десятки тысяч? 1.51*10000=15100 коп или 151 руб. А если не по 10 кубов?
Как тогда сводить баланс?
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40082504
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Правильный Вася
andrey_anonymous
пропущено...

В области финансов и налогов данный тезис не особо применим.

Ложное мнение.
....
Как тогда сводить баланс?


Округлять до копеек резезультат, а не расчетные коефициенты

.....
stax
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40082528
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поставщик, который покупает миллионы кубометров за миллионы рублей, разумеется получит "супердробные" цены.
Только потребителя всё это никак не касается - цена в квитке обязана быть в (целых) рублях и копейках, а "дробность потребления" определяется возможностями (индивидуального) счётчика.
Поэтому, да - исходные данные перемножаются как есть, сумма тоже округляется до (целых) рублей и копеек.
А уж как при этом изменится финансовый результат (прибыль) поставщика ... "Проблемы шерифа индейцев не волнуют".

P.S.
Да, "это" работает в обе стороны.
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40082544
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Правильный Вася
Стоимость кубометра газа 5.56151 руб.

Стоимость услуги = округлить до копеек (объем*цена).
Попытка избавиться от округления на этом этапе будет фатальна.
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40082805
Правильный Вася
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous
Правильный Вася
Стоимость кубометра газа 5.56151 руб.

Стоимость услуги = округлить до копеек (объем*цена).

Именно об этом я и говорю. Считать без округлений. А показывать уже округлённый итог.
Так и у топикстартера - считать доли суток без округлений (равно как и хранить между подсчётами), а показывать сумму уже округлённой. Тогда не будет этих 0.999 вместо 1.000
...
Рейтинг: 0 / 0
нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
    #40082806
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Правильный Вася
andrey_anonymous
пропущено...
Стоимость услуги = округлить до копеек (объем*цена).

Именно об этом я и говорю. Считать без округлений
у меня разрыв шаблона
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / нужно разделить единицу так , чтоб в итоге сумма частеи вернулась в 1.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]