SQL: Как корректно вернуть 100 * Some / Total, если Total может быть 0
create table test( value double, total double);
insert into test (value, total) values (1.0,100.0);
insert into test (value, total) values (2.0, 0.0);
insert into test (value, total) values (3.0,300.0);
SELECT value, total, 100 * value / total AS percent FROM test where total != 0
UNION SELECT value, total, 0 FROM test where total = 0;
SELECT value, total, case when total=0 then null else 100 * value / total end AS percent FROM test
Если total может быть и отрицательным, лучше не усложнять функцию, а проводить сравнение имхо
Прекрасно, спасибо!
я не помню case входит в стандарт SQL или нет, а под Oracle точиться влом было.
нет, а под Oracle точиться влом было.Не знаю что там с Ораклом, но у меня в T-SQL работает.
так пишут математики. О чем тебе должны были сказать еще на первом курсе в рамках линейной алгебры, в теме регуляризации.
ты же физик, вот за них и говори.
это такой способ дискредитировать математиков что-ли?предложенный мидори способ удобный для тех случаев: когда формулы сложные, но адекватные (т.е. деление на ноль происходит только в тех случаях, когда и делимое тоже ноль).
ты же физик, вот за них и говори.
допустим:
a1..n и b1..n - не отрицательные числа
A = sum(a1. ..an)
B = sum(b1..bn)
дальше надо записать формулу вида
k1 = a1/A + b1/B;
через предложенный midori способ это записывается
k1 = a1/notnull(A) + b1/notnull(B);
где notnull функция вида return x == 0? 1: x;
через if-ы это записывается страшнее:
k1 = 0
if (A != 0)
k1 += a1/A;
if (B != 0)
k1 += b1/B;
тем более, что в таком виде как ты написал, способ неприменим, т.к. в добавок надо описывать то, как ты потом будешь отличать реальные данные от треша.
если пугает множество ифов, то такие функции можно вынести в хранимые процедуры.
если пугает скорость вычисления, то можно скомпилировать на сях и зафигачить как модуль.
а то, что описал мидори я бы стал применять лишь для того, чтобы проверить какую-нибудь идею "на коленке", но ни как в качестве рабочего способа.
тем более, что в таком виде как ты написал, способ неприменим, т.к. в добавок надо описывать то, как ты потом будешь отличать реальные данные от треша.откуда возьмется треш?
в mysql по крайней мере ничего специального для этого делать не надо:
mysql> select 1/0;
+------+
| 1/0 |
+------+
| NULL |
+------+
1 row in set (0.00 sec)
а что разве по стандарту деление на 0 само по себе не возвращает null безо всяких case-ов?afaik, ошибка должна быть
ps
oracle и ms sql выдают ошибку
Его решение тоже адекватно. Но мне больше понравилось с case'ами.
например, в общем случае такого сделать нельзя, если пользоваться плавающей точкой.
под трешем я имею ввиду те значения, где должен получиться inf или nan - как ты их отличишь от остальных?а почему при таком решений такие числа должны появиться?
меня беспокоит то, что по исходной постановке некорректные значения станут корректными и будут выглядеть также как и все остальные
предложенный мидори способ удобный для тех случаев: когда формулы сложные, но адекватныея бы не доверил считать свои деньги программисту, для которого применение условного оператора вызывает сложности, и он начинает искать обходные пути.
А ваще, на SQL сложные, большие формулы никто не считает.
В данном случае ни вопросы скорости, ни вопросы ясности кода не играют никакой существенной роли. Однако мне в голову не могло прийти, что аскера интересовало столь очевидное решение просто сравнить с нулем.
Почему не 0.000001?
Почему не 0.00000001?
Почему не 0.00000000001?
Почему не 0.00000000000001?
Почему не 0.0000000000000001?
Почему не 0.0000000000000000001?
Почему не 0.0000000000000000000001?
Почему не 0.00000000000000000000001?
Или 0.00000000000000000000000000001 ещё больше делает код нечитаемым?
ps. Это примерно как на физпраке сказать "достаточно малая величина". Тут же (100%) получишь контрольный вопрос в лоб - насколько малая?
потому что очевидно, что автор может сам решить, какой именно величины ему достаточно.
> Тут же (100%) получишь контрольный вопрос в лоб - насколько малая?
У тебя какие-то фобии в отношении физпрака? Я всегда знаю, насколько малой должна быть величина в конкретных случаях, когда я ее использую, и этот "контрольный вопрос в лоб" я задаю себе перед тем, как использовать величину, а не после.
Да чего вы привязались к человеку? Нормальный совет он дал, для большинства случаев подходит.
Оставить комментарий
agaaaa
Интересует запрос вида , но не вылетающий если в таблице есть поля с total = 0.