Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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.047 c
1-1159007734
Дмитрий В
2006-09-23 14:35
2006.11.05
Как записать байт в lpt порт


3-1157535205
Orxan
2006-09-06 13:33
2006.11.05
SQL Monitor


3-1157371577
ANB
2006-09-04 16:06
2006.11.05
Кто понимает смысл ошибки "Таблица мутирует" ?


15-1161085200
Маска
2006-10-17 15:40
2006.11.05
Firewall


15-1160590597
стьюдентЪ
2006-10-11 22:16
2006.11.05
Что вы делаете для души ?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский