![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Нужно упростить запрос [MSSQL]
Ольга © (2009-07-07 11:22:00)В таблице есть поле 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
Ольга (2009-07-08 09:03:00) [21]
> в 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
Всем огромное спасибо за помощь!
Кщд (2009-07-08 08:27:00) [22]>Вариант (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 07:26:00) [23]
> Кщд (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 05:42:00) [24]>topS (07.07.09 15:02) [19]
как они хранят десять валенок(ов?) - мне неведомо
если подходить строго математически, то сказано было четко - дробная часть их(валенок) кол-во
>Вариант (07.07.09 14:11) [16]
не читатель?
Anatoly Podgoretsky (2009-07-07 15:58:00) [25]> Вариант (07.07.2009 14:11:16) [16]
Умножить можно, но не известно на сколько.
topS (2009-07-07 15:02:00) [26]
> Кщд (07.07.09 14:53) [18]
кому нужны ошметки валенок?
Кщд (2009-07-07 14:53:00) [27]>topS (07.07.09 14:36) [17]
>дробная - количество "валенок".
topS (2009-07-07 14:36:00) [28]> Ольга © (07.07.09 11:54) [3]
> ...целая часть - количество "табуреток", дробная - количество "валенок".
0.1 это сколько валенок, 1 или 10? а может быть 1000000?
Вариант (2009-07-07 14:11:00) [29]
> Ольга © (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 или сколько знаков дробной там надо учесть прямо в запросе?
Кщд (2009-07-07 13:48:00) [30]>Ольга © (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)
ANB (2009-07-07 13:04:00) [31]
> количество "валенок" нужно несколько раз использовать в
> предлжении WHERE
сделай вложенный запрос и не парься.
Ольга (2009-07-07 12:53:00) [32]И так, табуретки теперь преобразовываются просто. А с "валенками" не получается:
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
Ольга (2009-07-07 12:26:00) [33]Попробовала с numeric - стало еще хуже, в дробной части незначимые нули.
> SELECT ROUND(150.75, 0, 1);
А вот это вроде то, что надо (до последней строчки мануала не дочитала)
Кщд (2009-07-07 12:20:00) [34]>Ega23 © (07.07.09 12:17) [10]
тогда строго из BOL:
SELECT ROUND(150.75, 0, 1);
GO
Ega23 (2009-07-07 12:17:00) [35]
> ну, а если подумать, то нечто вроде:
> round(x - 0.5)
Не факт.
Кщд (2009-07-07 12:16:00) [36]>Ольга © (07.07.09 11:59) [5]
ну, а если подумать, то нечто вроде:
round(x - 0.5)
Anatoly Podgoretsky (2009-07-07 12:16:00) [37]> Ольга (07.07.2009 11:54:03) [3]
Я вообще много чудес видел, но данный заказчик всех переплюнул.
Anatoly Podgoretsky (2009-07-07 12:15:00) [38]> Ольга (07.07.2009 11:59:05) [5]
Зато 956.5 - Int(Num) не округляют
Anatoly Podgoretsky (2009-07-07 12:13:00) [39]> Ольга (07.07.2009 11:54:03) [3]
Вероятнее всего получишь 0.33333 валенка
Ольга (2009-07-07 11:59:00) [40]
> floor, round, ceiling не работают?
Эти функции округляют: 956.5 -> 957 5