Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.10.31;
Скачать: CL | DM;

Вниз

Нужно упростить запрос   Найти похожие ветки 

 
Ольга ©   (2009-07-07 11:22) [0]

В таблице есть поле float. В запросе это поле нужно представить в виде двух натуральных чисел - целая и дробная части без округлений.
Делаю с помощью строковых функций - получилась громоздкая конструкция. Уверена, что можно сделать проще, не могу найти как.

IF object_id("tempdb..#tmp") is not null DROP TABLE #tmp
CREATE TABLE #tmp(val2 float)
INSERT INTO #tmp VALUES (-956.5)

SELECT  ABS(cast(CASE WHEN CHARINDEX(".",cast(val2 as varchar(20)))>0
 THEN substring(cast(val2 as varchar(20)),1,CHARINDEX(".",cast(val2 as varchar(20)))-1)
 ELSE NULL END as int)),
    cast(CASE WHEN CHARINDEX(".",cast(val2 as varchar(20)))>0
 THEN substring(cast(val2 as varchar(20)),CHARINDEX(".",cast(val2 as varchar(20)))+1,2)
 ELSE NULL END as int)
FROM #tmp


 
Ega23 ©   (2009-07-07 11:26) [1]

Я бы в numeric сначала попробовал скастовать, а дальше уже с ним игрался бы.


 
MsGuns ©   (2009-07-07 11:43) [2]

А зачем понадобилась дробная часть плавающего числа как целое БЕЗ ОКРУГЛЕНИЯ ?


 
Ольга ©   (2009-07-07 11:54) [3]


> А зачем понадобилась дробная часть плавающего числа как
> целое БЕЗ ОКРУГЛЕНИЯ

Так у заказчика хранятся данные (таблица создана до рождения Билла Гейтса): целая часть - количество "табуреток", дробная - количество "валенок". Делаю нормальную БД, нужно перенести данные.


 
Кщд   (2009-07-07 11:54) [4]

>Ольга ©   (07.07.09 11:22)  
floor, round, ceiling не работают?


 
Ольга ©   (2009-07-07 11:59) [5]


> floor, round, ceiling не работают?

Эти функции округляют: 956.5 -> 957  5


 
Anatoly Podgoretsky ©   (2009-07-07 12:13) [6]

> Ольга  (07.07.2009 11:54:03)  [3]

Вероятнее всего получишь 0.33333 валенка


 
Anatoly Podgoretsky ©   (2009-07-07 12:15) [7]

> Ольга  (07.07.2009 11:59:05)  [5]

Зато 956.5 - Int(Num) не округляют


 
Anatoly Podgoretsky ©   (2009-07-07 12:16) [8]

> Ольга  (07.07.2009 11:54:03)  [3]

Я вообще много чудес видел, но данный заказчик всех переплюнул.


 
Кщд   (2009-07-07 12:16) [9]

>Ольга ©   (07.07.09 11:59) [5]
ну, а если подумать, то нечто вроде:
round(x - 0.5)


 
Ega23 ©   (2009-07-07 12:17) [10]


> ну, а если подумать, то нечто вроде:
> round(x - 0.5)


Не факт.


 
Кщд   (2009-07-07 12:20) [11]

>Ega23 ©   (07.07.09 12:17) [10]
тогда строго из BOL:
SELECT ROUND(150.75, 0, 1);
GO


 
Ольга ©   (2009-07-07 12:26) [12]

Попробовала с numeric - стало еще хуже, в дробной части незначимые нули.

> SELECT ROUND(150.75, 0, 1);

А вот это вроде то, что надо (до последней строчки мануала не дочитала)


 
Ольга ©   (2009-07-07 12:53) [13]

И так, табуретки теперь преобразовываются просто. А с "валенками" не получается:

IF object_id("tempdb..#tmp") is not null DROP TABLE #tmp
CREATE TABLE #tmp(val2 float)
INSERT INTO #tmp VALUES (-956.5)
INSERT INTO #tmp VALUES (959.49)

SELECT ABS(cast(ROUND(val2,0,1) as int)),
      cast(CASE WHEN CHARINDEX(".",cast(val2 as varchar(20)))>0
  THEN substring(cast(val2 as varchar(20)),CHARINDEX(".",cast(val2 as varchar(20)))+1,2)
  ELSE NULL END as int)
FROM #tmp  ELSE NULL END as int)

Есть еще идеи? Это мне нужно не из любви к искусству, количество "валенок" нужно несколько раз использовать в предлжении WHERE


 
ANB   (2009-07-07 13:04) [14]


> количество "валенок" нужно несколько раз использовать в
> предлжении WHERE

сделай вложенный запрос и не парься.


 
Кщд   (2009-07-07 13:48) [15]

>Ольга ©   (07.07.09 12:53) [13]
>CHARINDEX("."
в MS SQL разделитель не зависит от локали?)

если абстрактно, то:
целая часть: ABS(cast(ROUND(val2,0,1) as int))
=> дробная: frac = abs(val2) - ABS(cast(ROUND(val2,0,1) as int))
=> искомое int2 = cast(frac * power(10, len(cast(frac as varchar(20)))-2) as int)


 
Вариант   (2009-07-07 14:11) [16]


> Ольга ©   (07.07.09 12:53) [13]


Поиграй с запросом

DECLARE @N  float;
SET @N=-750.158;

select ROUND(@N,0,1) as C,ROUND(@N-ROUND(@N,0,1),3) as FR

А если и дробную часть надо как целую, то почему бы ее не умножить... на 10 или 100 или 1000  или сколько знаков дробной там надо учесть прямо в запросе?


 
topS   (2009-07-07 14:36) [17]

> Ольга ©   (07.07.09 11:54) [3]
> ...целая часть - количество "табуреток", дробная - количество "валенок".

0.1 это сколько валенок, 1 или 10? а может быть 1000000?


 
Кщд   (2009-07-07 14:53) [18]

>topS   (07.07.09 14:36) [17]

>дробная - количество "валенок".


 
topS   (2009-07-07 15:02) [19]


> Кщд   (07.07.09 14:53) [18]

кому нужны ошметки валенок?


 
Anatoly Podgoretsky ©   (2009-07-07 15:58) [20]

> Вариант  (07.07.2009 14:11:16)  [16]

Умножить можно, но не известно на сколько.


 
Кщд   (2009-07-08 05:42) [21]

>topS   (07.07.09 15:02) [19]
как они хранят десять валенок(ов?) - мне неведомо
если подходить строго математически, то сказано было четко - дробная часть их(валенок) кол-во

>Вариант   (07.07.09 14:11) [16]
не читатель?


 
Вариант   (2009-07-08 07:26) [22]


> Кщд   (08.07.09 05:42) [21]

Писатель?


> Anatoly Podgoretsky ©   (07.07.09 15:58) [20]


Понятно, если это так. Но я вижу код
> Ольга ©   (07.07.09 12:53) [13]


substring(cast(val2 as varchar(20)),CHARINDEX(".",cast(val2 as varchar(20)))+1,2) , где после запятой берется 2 символа - то есть количество вроде как от 0 до 99. Умножить на 100 в этом случае... А будет до 1000, ну будут умножать на 1000 и т.д.
Хотя в общем согласен с
>  Anatoly Podgoretsky ©   (07.07.09 12:16) [8]


 
Кщд   (2009-07-08 08:27) [23]

>Вариант   (08.07.09 07:26) [22]
ветку-то недосуг прочитать перед тем, как постить?

>substring(cast(val2 as varchar(20)),CHARINDEX(".",cast(val2 as >varchar(20)))+1,2)
в MS SQL разделитель не зависит от локали?


 
Ольга ©   (2009-07-08 09:03) [24]


> в MS SQL разделитель не зависит от локали?

Данные хранятся с точкой. Запятая используется только для отображения (в зависимости от локали).


> substring(cast(val2 as varchar(20)),CHARINDEX(".",cast(val2
> as varchar(20)))+1,2) , где после запятой берется 2 символа
> - то есть количество вроде как от 0 до 99

Да, здесь моя ошибка. Я не знаю сколькозначная цифра может встретиться после запятой (двойку поставила, визуально оценив несколько страниц - вроде цифры маленькие). Пример в [15] работает правильнее, хоть и выраженьице получается тоже не особо удобоваримое, ну да бог с ним, SQL-сервер переварит.


> сделай вложенный запрос и не парься

Попыталась, запарилась. Запрос из одной таблицы. Даже если объединить ее саму с собой, все равно во WHERE нужна связка по табуреткам и валенкам. Или я не поняла идеи.

Привожу окончательный код:

IF object_id("tempdb..#tmp") is not null DROP TABLE #tmp
CREATE TABLE #tmp(val2 float)
INSERT INTO #tmp VALUES (-956.5)
INSERT INTO #tmp VALUES (959.449)

SELECT ABS(cast(ROUND(val2,0,1) as int)),
      cast((abs(val2) - ABS(cast(ROUND(val2,0,1) as int))) * power(10, len(cast(abs(val2) -
      ABS(cast(ROUND(val2,0,1) as int)) as varchar(20)))-2) as int)
FROM #tmp
WHERE cast((abs(val2) - ABS(cast(ROUND(val2,0,1) as int))) * power(10, len(cast(abs(val2) -
     ABS(cast(ROUND(val2,0,1) as int)) as varchar(20)))-2) as int) BETWEEN 1 AND 10
     OR
     cast((abs(val2) - ABS(cast(ROUND(val2,0,1) as int))) * power(10, len(cast(abs(val2) -
     ABS(cast(ROUND(val2,0,1) as int)) as varchar(20)))-2) as int) > 50

Всем огромное спасибо за помощь!


 
Anatoly Podgoretsky ©   (2009-07-08 09:13) [25]

> Ольга  (08.07.2009 09:03:24)  [24]

Ответь на вопрос, как точно хранится 1 валенок и 10 валенок


 
topS   (2009-07-08 09:16) [26]


> Ольга ©   (08.07.09 09:03) [24]

и всё же, почему вдруг -956.5 это 5 валенок, а не 500?
и как "изобразить" эти самые 500 валенок?
и почему устраивает, если 959.499999 это 499999 валенка, а 959.4999999 это 4 валенка?


 
Вариант   (2009-07-08 09:19) [27]


> Кщд   (08.07.09 08:27) [23]

иии ??? Я где-то об этом упоминал?

Наверное ты хочешь сказать, что твой вариант единственно верный и нужный? С уважением к твоим знаниям и не собираясь отнять лавры первого помогшего, я просто привел свой вариант, без длинных cast. И даже не полный вариант, а только как "подумать" для автора вопроса. Ей понравился твой - я рад за тебя.


> Ольга ©   (08.07.09 09:03) [24]


> Да, здесь моя ошибка. Я не знаю сколькозначная цифра может
> встретиться после запятой

Тогда задача не решаема. Или надо передавать хотя бы количество значащих цифр параметром в запрос.


 
Вариант   (2009-07-08 09:23) [28]


> Вариант   (08.07.09 09:19) [27]


Хотя правильней - это знать ответы на вопросы

> Anatoly Podgoretsky ©   (08.07.09 09:13) [25]


> topS   (08.07.09 09:16) [26]


 
Anatoly Podgoretsky ©   (2009-07-08 09:33) [29]

Задача имеет решение только для чисел не оканчивающихся на НОЛЬ и то частичное, поскольку float имеет относительную точность и абсолютное большинство чисел можно представить только приблизительно.
Следует также добавить, что любые операции с числами меняют эту точность.


 
Anatoly Podgoretsky ©   (2009-07-08 09:34) [30]


> Так у заказчика хранятся данные (таблица создана до рождения
> Билла Гейтса): целая часть - количество "табуреток", дробная
> - количество "валенок". Делаю нормальную БД, нужно перенести
> данные.

Если у заказчика есть бумажная база, то надо просто заставить ввести валенки вручную


 
Кщд   (2009-07-08 09:42) [31]

>Вариант   (08.07.09 09:19) [27]
какие лавры?
о чем Вы?)
>Кщд   (07.07.09 12:20) [11]


 
Вариант   (2009-07-08 10:20) [32]


> Кщд   (08.07.09 09:42) [31]

Значит я не понял о чем ты. Задай вопрос еще раз, только что бы мне не пришлось угадывать смысл, есть какие-то замечания -напиши, аргументируй - отвечу.


 
Ольга ©   (2009-07-08 13:37) [33]

В эту таблицу пишет некий фортрановский модуль, и пишет аккуратно (видимо с округлением). Так что цифр с периодом в дробной части в ней нет.
956.5   - 5 валенков
956.50 - 50 валенков
Если встретится 0.4999 - видимо, будет 4999 валенков (но такого пока не встречалось).

> Если у заказчика есть бумажная база, то надо просто заставить
> ввести валенки вручную

Нашего Заказчика замучаешься заставлять... А вот бабок за эту работу можно неплохо срубить :)


 
Ольга ©   (2009-07-08 13:51) [34]


> 956.50 - 50 валенков

Написала это пример с потолка, потом поняла, что во float .50  не записать.
Народ, каюсь - все остальные поля, коих немерено в этой таблице, float, а одно это поле sql_variant. Простите, что ввела в заблуждение.


 
Anatoly Podgoretsky ©   (2009-07-08 13:59) [35]

> Ольга  (08.07.2009 13:37:33)  [33]

Для чисел, что ,5 что ,5000 это одно и тоже и нельзя различить. Существует вариант прямой, извращеной записи прямо в файл таблицы, но это врядли, вероятнее это поле не Float/Number


 
Вариант   (2009-07-08 14:09) [36]


> Ольга ©   (08.07.09 13:51) [34]

"Просто хочется рвать и метать!" (c) Бывалов из х/ф "Волга-Волга" :-)


 
Ольга ©   (2009-07-08 14:11) [37]


> Вариант   (08.07.09 14:09) [36]

Посыпаю голову пеплом...


 
Anatoly Podgoretsky ©   (2009-07-08 14:16) [38]

> Ольга  (08.07.2009 13:51:34)  [34]

Тогда хуже, поскольку там может быть что угодно, включая пользовательские типы.


 
Anatoly Podgoretsky ©   (2009-07-08 14:24) [39]


> Так у заказчика хранятся данные (таблица создана до рождения
> Билла Гейтса): целая часть - количество "табуреток", дробная
> - количество "валенок". Делаю нормальную БД, нужно перенести
> данные.

И вряд ли это из-за низкой квалификации, судя по последним данным квалификация высокая.


 
Ольга ©   (2009-07-08 14:30) [40]


> Тогда хуже, поскольку там может быть что угодно, включая
> пользовательские типы.

"Там" это где? Это "кривенькое" поле мы разобрали по косточкам, информация в нем однородная... Каких сюрпризов можно ждать?



Страницы: 1 2 вся ветка

Текущий архив: 2010.10.31;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.011 c
2-1281369967
DROWSY
2010-08-09 20:06
2010.10.31
TIBCustomDataSet .RecordCount


2-1281087136
Xmen
2010-08-06 13:32
2010.10.31
Сохранение Jpg файлов в базе Оракла


15-1277731999
Marser
2010-06-28 17:33
2010.10.31
Встреча века


2-1280992809
бумбум
2010-08-05 11:20
2010.10.31
как правильно сделать условие "или" в SQL запросе


8-1207328480
Alexus
2008-04-04 21:01
2010.10.31
Работа с графиком