Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2010.10.31;
Скачать: [xml.tar.bz2];

Вниз

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

 
Ольга ©   (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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.55 MB
Время: 0.006 c
2-1281337357
George
2010-08-09 11:02
2010.10.31
Файл в строку или как?


2-1280958303
Ярослав
2010-08-05 01:45
2010.10.31
D2010 и ресурсы


15-1279608783
abun
2010-07-20 10:53
2010.10.31
Ложное срабатывание Trojan.Win32.StartPage


15-1279861656
И. Павел
2010-07-23 09:07
2010.10.31
Экологическая политика


2-1280993419
12
2010-08-05 11:30
2010.10.31
Что-то глючит, AV непонятно-плавающий.





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский