Форум: "Базы";
Текущий архив: 2006.11.05;
Скачать: [xml.tar.bz2];
ВнизНеправильный расчет выражений в SQL Найти похожие ветки
← →
Delphi basic © (2006-09-01 10:59) [0]В Firebird выполняю следующий запрос:
select (ts.moto_hour * c.fuel_norm_moto), c.fuel_norm_moto, ts.moto_hour
from travel_sheet ts, car c, subdivision s
where ts.car = c.ui and
ts.subdivision = s.ui and
extract(month from ts.work_date) = 7 and
extract(year from ts.work_date) = 2006 and
s.code = "СМИТ" and
ts.state = 1
результаты:
150 20 7,5
75 20 3,8
60 6 6
60 20 3
почему выражение (1-й столбец) неправильно считается?
Чего-то я не понимаю :(
← →
ANB © (2006-09-01 11:06) [1]приведи DDL всех таблиц и куски данных.
← →
Delphi basic © (2006-09-01 11:14) [2]ОК, вот:
1-я табл
CREATE TABLE TRAVEL_SHEET (
UI INTEGER NOT NULL,
CAR INTEGER NOT NULL,
DRIVER INTEGER NOT NULL,
SUBDIVISION INTEGER NOT NULL,
EXPENSE_CIPHER INTEGER NOT NULL,
PREFIX VARCHAR(10) NOT NULL,
NUMBER INTEGER NOT NULL,
BEGIN_DATE DATE NOT NULL,
END_DATE DATE NOT NULL,
STATE INTEGER NOT NULL,
WORK_DATE DATE NOT NULL,
SPEEDOMETER_BEFORE INTEGER NOT NULL,
SPEEDOMETER_AFTER INTEGER NOT NULL,
REMAINDER_BEFORE NUMERIC(10,3) NOT NULL,
REMAINDER_AFTER NUMERIC(10,3) NOT NULL,
KM_CITY INTEGER DEFAULT 0 NOT NULL,
KM_CITY_CARGO INTEGER DEFAULT 0 NOT NULL,
CITY_CARGO NUMERIC(10,1) DEFAULT 0 NOT NULL,
KM_HIGHWAY INTEGER DEFAULT 0 NOT NULL,
KM_HIGHWAY_CARGO INTEGER DEFAULT 0 NOT NULL,
HIGHWAY_CARGO NUMERIC(10,1) DEFAULT 0 NOT NULL,
KM_FIELD INTEGER DEFAULT 0 NOT NULL,
MOTO_HOUR NUMERIC(10,1) DEFAULT 0 NOT NULL,
FUEL_ISSUED NUMERIC(10,3) DEFAULT 0 NOT NULL,
MECH_HOUR NUMERIC(10,1) DEFAULT 0 NOT NULL,
FUEL_USED NUMERIC(10,3) DEFAULT 0 NOT NULL
);
2-я табл:
CREATE TABLE CAR (
UI INTEGER NOT NULL,
MARK INTEGER NOT NULL,
CAR_TYPE INTEGER NOT NULL,
DRIVER INTEGER NOT NULL,
GSM_CARD INTEGER NOT NULL,
SUBDIVISION INTEGER NOT NULL,
GSM_TYPE INTEGER NOT NULL,
GOS_NUMBER VARCHAR(10) NOT NULL,
YEAR_ISSUE INTEGER NOT NULL,
USAGE_BEGIN DATE,
USAGE_END DATE,
FUEL_NORM NUMERIC(5,1) NOT NULL,
FUEL_NORM_MOTO NUMERIC(5,1) NOT NULL,
GARAGE_NUMBER VARCHAR(10),
AVERAGE_SPEED INTEGER DEFAULT 40 NOT NULL,
NO_USE_CORR_COEFF INTEGER DEFAULT 0 NOT NULL
);
куски данных как-то неудобочитаемы будут, особенно для 1-й табл.
← →
ANB © (2006-09-01 11:16) [3]Эта, первичные ключи неплохо бы еще напечатать . . .
← →
Delphi basic © (2006-09-01 11:18) [4]У всех они по UI построены.
← →
Delphi basic © (2006-09-01 11:35) [5]Вот так считает правильно:
select (cast(ts.moto_hour as numeric(10, 1)) * cast(c.fuel_norm_moto as numeric(10, 1))), c.fuel_norm_moto, ts.moto_hour,
ts.UI, ts.car
from travel_sheet ts, car c, subdivision s
where ts.car = c.ui and
ts.subdivision = s.ui and
extract(month from ts.work_date) = 7 and
extract(year from ts.work_date) = 2006 and
s.code = "СМИТ" and
ts.state = 1
Это что ж, получается, придется обязательно к одному типу приводить, чтобы получить корректный результат?
← →
ANB © (2006-09-01 11:43) [6]
> Delphi basic © (01.09.06 11:35) [5]
В оракле такие проблемы не возникают :)
← →
Delphi basic © (2006-09-01 11:51) [7]Я знаю, но "каждому свое" ©
В смысле проекту в зависимости от масштаба.
На оракле у нас корпоративная АСУ - тот еще мастодонтище :)
← →
Desdechado © (2006-09-01 12:10) [8]провел эксперимент на FB 1.5.3
таблицы:
CREATE TABLE CAR (
UI INTEGER NOT NULL,
FUEL_NORM_MOTO NUMERIC(5,1) NOT NULL
);
UI FUEL_NORM_MOTO
1 20,000
2 20,000
3 6,000
4 20,000
CREATE TABLE TRAVEL_SHEET (
UI INTEGER NOT NULL,
MOTO_HOUR NUMERIC(10,1) DEFAULT 0 NOT NULL
);
UI MOTO_HOUR
1 7,500
2 3,800
3 6,000
4 3,000
запрос:
select (ts.moto_hour * c.fuel_norm_moto), c.fuel_norm_moto, ts.moto_hour
from travel_sheet ts, car c
where ts.ui = c.ui
получил такое
F_1 FUEL_NORM_MOTO MOTO_HOUR
150,000 20,000 7,500
76,000 20,000 3,800
36,000 6,000 6,000
60,000 20,000 3,000
делаем выводы...
PS AFAIR, операнды автоматически приводятся к большему типу
← →
Delphi basic © (2006-09-01 12:16) [9]У меня та же версия FB, но без CAST"ов упорно не хочет правильно считать.
← →
Delphi basic © (2006-09-01 12:18) [10]
> Desdechado © (01.09.06 12:10) [8]
Какой диалект у базы? У моей 3-й.
← →
Виталий Панасенко (2006-09-01 12:23) [11]Не через БДЕ случаем ?
← →
Delphi basic © (2006-09-01 12:32) [12]В IBExpert"е
← →
Desdechado © (2006-09-01 12:36) [13]диалект 1, но имхо на числа это не должно влиять
← →
Delphi basic © (2006-09-01 13:03) [14]
> Desdechado © (01.09.06 12:10) [8]
Провел тот же эксперимент с двумя базами, с 1-м и 3-м диалектом. Считает правильно... Так какого рожна в исходной базе ему надо?
← →
unknown © (2006-09-01 13:57) [15]
> Desdechado © (01.09.06 12:36) [13]
Очень даже влияет :
NUMERIC
диалект 3 - 64 bit int
диалект 1 - double precision
← →
Desdechado © (2006-09-01 14:06) [16]да, подзабыл
просто с фиксированной точкой да и 3-м диалектом редко пользуюсь
Precision Dialect 1 Dialect 3
1 to 4 SMALLINT for NUMERIC datatypes SMALLINT
INTEGER for DECIMAL datatypes
5 to 9 INTEGER INTEGER
10 to 18 DOUBLE PRECISION INT64
Но это всего лишь способ ХРАНЕНИЯ, а не выполнения матем. операций
← →
Delphi basic © (2006-09-01 14:09) [17]
> unknown © (01.09.06 13:57) [15]
Точно? Я в хелпе интербейзовском вычитал много чего интересного, например, то, что numeric для size <= 9 хранит как Integer для обоих диалектов, а начиная с size 10 - как double precision/64 bit в зависимости от диалекта.
← →
Delphi basic © (2006-09-01 14:20) [18]
> Delphi basic © (01.09.06 13:03) [14]
Но результаты [14] все равно непонятны...
Если уж считать неправильно, то делать это применительно ко всем базам на одном и том же сервере...
← →
Виталий Панасенко (2006-09-02 11:29) [19]backup/restore не делал ? может, база рухнула ?
← →
kaif © (2006-09-05 01:09) [20]Я сталкивался с подобной ошибкой.
Если перемножается INTEGER и DECIMAL (NUMERIC)
зачастую FB рассматривает результат как INTEGER.
Использование CAST всегда спасает.
← →
atruhin © (2006-09-05 17:02) [21]> зачастую FB рассматривает результат как INTEGER.
Вроде не зачастую, а всегда. Это документированно.
А вот то, что у автора похоже на
> [19] Виталий Панасенко (02.09.06 11:29)
← →
Desdechado © (2006-09-05 17:07) [22]Комбинируем
> FUEL_NORM_MOTO NUMERIC(5,1)
и
>Precision Dialect 1 Dialect 3
>5 to 9 INTEGER INTEGER
и
kaif © (05.09.06 01:09) [20]
Может, каким-то боком и вылазит?
← →
Delphi basic © (2006-09-06 11:06) [23]
> Виталий Панасенко (02.09.06 11:29) [19]
Сделал, теперь нормально считает.
> atruhin © (05.09.06 17:02) [21]
> А вот то, что у автора похоже на
> > [19] Виталий Панасенко (02.09.06 11:29)
И все же почему так странно себя ведет?
Получается, если не сделал backup/restore в какой-то (какой?) момент времени, можно получить сюрпризы с непонятно откуда растущими ногами вроде того, который был у меня? Ведь остальное все нормально работало.
← →
Desdechado © (2006-09-06 13:35) [24]> можно получить сюрпризы с непонятно откуда растущими ногами
Сюрпризы всегда возможны. А b/r вполне нормальная процедура, рекомендуется для периодичного выполнения. Можно и gfix.
← →
atruhin © (2006-09-07 15:33) [25]> [23] Delphi basic © (06.09.06 11:06)
> Получается, если не сделал backup/restore в какой-то (какой?
> ) момент времени, можно получить сюрпризы
Не совсем так. Ошибки базы бывают как правило после "падения" сервера, а также восле модификации структуры БД. В некоторых случаях когда в таблице есть данные, и ты изменяешь тип поля, в поле могут оказаться неправильные данные. Это известный глюк IB. При нормальной работе база может работать годами без b/r. ( видел такие случаи)
← →
Desdechado © (2006-09-07 15:36) [26]> При нормальной работе база может работать годами без b/r
Особенно в режиме R/O с компашки :)
А то ведь предел нумерации транзакций когда-то же наступит...
> Это известный глюк IB.
Документированный глюк - это фича!
← →
atruhin © (2006-09-07 17:16) [27]> А то ведь предел нумерации транзакций когда-то же наступит...
Ну, ну :) Счетчик = integer;
Основная цель b/r - удаление зависших транзакций, пересчет статистики индексов. (Это для аатора)
← →
Desdechado © (2006-09-07 17:35) [28]> пересчет статистики индексов.
Перестройка индексов. Пересчет статистики можно сделать и без b/r командой SET STATISTICS. А в бэкапе индексы не хранятся, только правила их построения.
Хотя и индексы можно перестроить (INACTIVE/ACTIVE), но это уже другая песня.
← →
atruhin © (2006-09-07 20:34) [29]Да я то знаю, все можно сделать отдельно, но бэкап это все делает сразу, автоматически.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2006.11.05;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.042 c