Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 И все же число прописью, как?  [new]
MSSQLuserK1
Member

Откуда:
Сообщений: 14
Всем доброго времени суток!
Обращаюсь к Вам за помощью.
есть такие входные данные в mssql:
SELECT CONVERT(DECIMAL(10,3), 53.5)
результат 53.500
Это все делается convert-ом в varchar чтобы не обрезались 0, нужны числа именно до тысячных.
Как средствами sql можно вывести эти данные в формате: "пятьдесят три целых пятьсот тысячных"?
Особенность еще в том, что все будет делаться внутри другого select из которого также выводятся другие данные.
Заранее спасибо!
28 янв 17, 16:55    [20156902]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
invm
Member

Откуда: Москва
Сообщений: 8853
http://morpher.ru/Products/DLL/SQLServer.aspx
28 янв 17, 17:56    [20157062]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
aleks2
Guest
invm
http://morpher.ru/Products/DLL/SQLServer.aspx


Ога.

Написать "все варианты" для числительных - хватит таблички в "тыщу строк" и инлайн-функции.
28 янв 17, 18:32    [20157148]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
Александра77
Member

Откуда:
Сообщений: 12
на делфи/VBA... есть десятки функций, преобразования цифры в строку ;)
Выгрузку же все равно будете в чём то делать, вот это и заставить трудиться! А MSSQL тут не причём. По моему скромному мнению ;)
28 янв 17, 18:56    [20157198]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
invm
Member

Откуда: Москва
Сообщений: 8853
aleks2
Написать "все варианты" для числительных - хватит таблички в "тыщу строк" и инлайн-функции.
Ну так поделись реализацией с общественностью.
28 янв 17, 20:01    [20157349]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
iap
Member

Откуда: Москва
Сообщений: 46899
Александра77
есть десятки функций, преобразования цифры в строку
Какой именно цифры?
28 янв 17, 21:08    [20157469]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
MSSQLuserK1
Member

Откуда:
Сообщений: 14
Один из вариантов в Delphi, FloatToText - но выводит только до "сотых"
И так как не факт что позже БД будет взаимодействовать с утилитой на Delphi, то логично сделать это (или попробовать сделать в sql)
Как то ограничить, возможных вариантов "списка всех цифр".
29 янв 17, 08:51    [20158135]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
aleks2
Guest
invm
aleks2
Написать "все варианты" для числительных - хватит таблички в "тыщу строк" и инлайн-функции.
Ну так поделись реализацией с общественностью.


declare @num table(num int primary key, spell nvarchar(128))

insert @num
  values -- 0 - 99
     (0, N'ноль'), (1, N'один'), (2, N'два'), (11, N'одинадцать'), (20, N'двадцать'), (99, N'девяносто девять'),
     -- 100 - 900
     (100, N'сто'), (200, N'двести'), (900, N'девятьсот'),
     -- 1 000 - 1 000 000
     (1000, N'одна тысяча'), (7000, N'семь тысяч'), (900000, N'девятьсот тысяч')
     -- далее ужо сами. Если хорошо подумать - далее все то же самое. Можно сэкономить.

declare @numParts table(n int primary key, num int)
insert @numParts
  values (1, 100), (2, 1000), (3, 1000000);

declare @n int = 7211;

with p as (select @n%num as p, nnum = @n%num, n = 1 from @numParts where n = 1
           union all
           select (@n - p.nnum)%np.num as p, nnum = @n%num, n = np.n from p inner join @numParts as np on np.n = p.n + 1
          )
 select * from p;


with p as (select @n%num as p, nnum = @n%num, n = 1 from @numParts where n = 1
           union all
           select (@n - p.nnum)%np.num as p, nnum = @n%num, n = np.n from p inner join @numParts as np on np.n = p.n + 1
          )
    select n.spell 
      from p inner join @num as n on p.p = n.num and p <> 0
      order by p.n desc
29 янв 17, 11:28    [20158234]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
invm
Member

Откуда: Москва
Сообщений: 8853
aleks2,

А падеж и род? А дробная часть?
Не устанешь таблицу заполнять?
29 янв 17, 12:18    [20158308]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
aleks2
Guest
invm
aleks2,

А падеж и род? А дробная часть?
Не устанешь таблицу заполнять?


Родов всего 3. Падежей не помню, но помню что не более 10.

Оценка сверху:
3x10x10000 = 300000

Не, ничего сложного в заполнении таблички не предвидится.

ЗЫ. Конечно, цитируемая DLL - это вершина искуcственного интеллекта, познавшая глубины русского языка.
29 янв 17, 15:33    [20158619]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
MSSQLuserK1
Member

Откуда:
Сообщений: 14
Morpher платный, да и сторонние dll не хочется подкидывать, так как факт их безопасности не установлен.(
30 янв 17, 11:04    [20160508]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
MaxusPerfectus
Member

Откуда: Москва
Сообщений: 11
Через скалярную функцию.

+
alter function dbo.fn_NumberToCursive_3N(@num bigint, @thousand bit) 
returns varchar(1000)
as
begin
	declare @return varchar(1000);
	select 
		@return = 
			t1.number_3 + iif(t1.number_3 <> '' and t1.number_2 <> '', ' ', '') + 
			t1.number_2 + iif(t1.number_2 <> '' and t1.number_1 <> '', ' ', '') + 
			t1.number_1
	from
	(
		select
			case 
				when @num = 0 then 'ноль'
				else 
					case
						when @num % 100 not between 11 and 19 and @num % 10 = 1 and @thousand = 0 then 'один'
						when @num % 100 not between 11 and 19 and @num % 10 = 1 and @thousand = 1 then 'одна'
						when @num % 100 not between 11 and 19 and @num % 10 = 2 and @thousand = 0 then 'два'
						when @num % 100 not between 11 and 19 and @num % 10 = 2 and @thousand = 1 then 'две'
						when @num % 100 not between 11 and 19 and @num % 10 = 3 then 'три'
						when @num % 100 not between 11 and 19 and @num % 10 = 4 then 'четыре'
						when @num % 100 not between 11 and 19 and @num % 10 = 5 then 'пять'
						when @num % 100 not between 11 and 19 and @num % 10 = 6 then 'шесть'
						when @num % 100 not between 11 and 19 and @num % 10 = 7 then 'семь'
						when @num % 100 not between 11 and 19 and @num % 10 = 8 then 'восемь'
						when @num % 100 not between 11 and 19 and @num % 10 = 9 then 'девять'
						else ''
					end
			end number_1,
			case
				when @num % 100 between 11 and 19 then
					case @num % 100
						when 11 then 'одинадцать'
						when 12 then 'двенадцать'
						when 13 then 'тринадцать'
						when 14 then 'четырнадцать'
						when 15 then 'пятнцадцать'
						when 16 then 'шестнадцать'
						when 17 then 'семнадцать'
						when 18 then 'восемнадцать'
						when 19 then 'девятнадцать'
					end
				when @num % 100 / 10 = 0 then ''
				when @num % 100 / 10 = 2 then 'двадцать'
				when @num % 100 / 10 = 3 then 'тридцать'
				when @num % 100 / 10 = 4 then 'сорок'
				when @num % 100 / 10 = 5 then 'пятьдесят'
				when @num % 100 / 10 = 6 then 'шестьдесят'
				when @num % 100 / 10 = 7 then 'семьдесят'
				when @num % 100 / 10 = 8 then 'восемьдесят'
				when @num % 100 / 10 = 9 then 'девяносто'
				else ''
			end number_2,
			case @num % 1000 / 100
				when 0 then ''
				when 1 then 'сто'
				when 2 then 'двести'
				when 3 then 'триста'
				when 4 then 'четыреста'
				when 5 then 'пятьсот'
				when 6 then 'шестьсот'
				when 7 then 'семьсот'
				when 8 then 'восемьсот'
				when 9 then 'девятьсот'
				else ''
			end number_3
	) t1

	return @return;
end
go

create function dbo.fn_NumberToCursive(@num bigint)
returns varchar(1000)
as
begin
	declare @return varchar(1000);
	select 
	@return =
		t1.number_5_text +
		case
			when t1.number_5_text = '' then ''
			when t1.number_5 % 100 between 11 and 19 then ' триллионов'
			when t1.number_5 % 10 = 0 and t1.number_5 <> 0 then ' триллионов'
			when t1.number_5 % 10 = 1 then ' триллион'
			when t1.number_5 % 10 between 5 and 9 then ' триллионов'
			when t1.number_5 % 10 between 2 and 4 then ' триллиона'
		end +
		iif(t1.number_5 <> 0 and t1.number_4 <> 0, ' ', '') +
		t1.number_4_text +
		case
			when t1.number_4_text = '' then ''
			when t1.number_4 % 100 between 11 and 19 then ' миллиардов'
			when t1.number_4 % 10 = 0 and t1.number_4 <> 0 then ' миллиардов'
			when t1.number_4 % 10 = 1 then ' миллиард'
			when t1.number_4 % 10 between 5 and 9 then ' миллиардов'
			when t1.number_4 % 10 between 2 and 4 then ' миллиарда'
		end +
		iif((t1.number_4 + t1.number_5) <> 0 and t1.number_3 <> 0, ' ', '') +
		t1.number_3_text +
		case
			when t1.number_3_text = '' then ''
			when t1.number_3 % 100 between 11 and 19 then ' миллионов'
			when t1.number_3 % 10 = 0 and t1.number_3 <> 0 then ' миллионов'
			when t1.number_3 % 10 = 1 then ' миллион'
			when t1.number_3 % 10 between 5 and 9 then ' миллионов'
			when t1.number_3 % 10 between 2 and 4 then ' миллиона'
		end +
		iif((t1.number_3 + t1.number_4 + t1.number_5) <> 0 and t1.number_2 <> 0, ' ', '') +
		t1.number_2_text +
		case
			when t1.number_2_text = '' then ''
			when t1.number_2 % 100 between 11 and 19 then ' тысяч'
			when t1.number_2 % 10 = 0 and t1.number_2 <> 0 then ' тысяч'
			when t1.number_2 % 10 = 1 then ' тысяча'
			when t1.number_2 % 10 between 5 and 9 then ' тысяч'
			when t1.number_2 % 10 between 2 and 4 then ' тысячи'
		end +
		iif((t1.number_2 + t1.number_3 + t1.number_4 + t1.number_5) <> 0 and t1.number_1 <> 0, ' ', '') +
		t1.number_1_text
	from 
	(
		select 
			dbo.fn_NumberToCursive_3N(@num, 0) number_1_text,
			cast(@num % 1000 as int) number_1,
			case
				when @num > 1000 then dbo.fn_NumberToCursive_3N(@num % 1000000 / 1000, 1) 
				else ''
			end number_2_text,
			cast(@num % 1000000 / 1000 as int) number_2,
			case
				when @num > 1000000 then dbo.fn_NumberToCursive_3N(@num % 1000000000 / 1000000, 0) 
				else ''
			end number_3_text,
			cast(@num % 1000000000 / 1000000 as int) number_3,
			case
				when @num > 1000000000 then dbo.fn_NumberToCursive_3N(@num % 1000000000000 / 1000000000, 0) 
				else ''
			end number_4_text,
			cast(@num % 1000000000000 / 1000000000 as int) number_4,
			case
				when @num > 1000000000000 then dbo.fn_NumberToCursive_3N(@num % 1000000000000000 / 1000000000000, 0) 
				else ''
			end number_5_text,
			cast(@num % 1000000000000000 / 1000000000000 as int) number_5
	) t1;

	return @return;
end
go



create function dbo.fn_NumberToCursive_Decimal(@num decimal(30,15))
returns varchar(1000)
as
begin
	declare @return varchar(1000) = '';
	declare
		@fractionalPartOfNumber bigint = 
			cast(replace(cast(cast(@num % 1 * 1000000000000000 as bigint) as varchar(100)), '0', '') as bigint),
		@integerPartOfNumber bigint = cast(@num as bigint);

	
	declare @fractionalPart_text varchar(100) = right(cast(@num as varchar(100)), 15);
	while (right(@fractionalPart_text, 1) = '0')
		set @fractionalPart_text = left(@fractionalPart_text, len(@fractionalPart_text) - 1);
	declare @fractionalPartLen bigint = len(@fractionalPart_text); 

	declare @fractionalPart varchar(1000) = ltrim(dbo.fn_NumberToCursive(@fractionalPartOfNumber));
	if right(@fractionalPart, 3) = 'два'
		set @fractionalPart = left(@fractionalPart, len(@fractionalPart) - 3) + 'две';

	select
		@return = 
			dbo.fn_NumberToCursive(@integerPartOfNumber) +
			case
				when @fractionalPartOfNumber = 0 then ''
				when @fractionalPartOfNumber = 1 then 
					case @fractionalPartLen
						when 1 then ' целых и одна десятая'
						when 2 then ' целых и одна сотая'
						when 3 then ' целых и одна тысячная'
						when 4 then ' целых и одна десятитысячная'
						when 5 then ' целых и одна стотысячная'
						when 6 then ' целых и одна милионная'
						when 7 then ' целых и одна десятимилионная'
						when 8 then ' целых и одна стомилионная'
						when 9 then ' целых и одна миллиардная'
						when 10 then ' целых и одна десятимиллиардная'
						when 11 then ' целых и одна стомиллиардная'
						when 12 then ' целых и одна триллионная'
						when 13 then ' целых и одна десятитриллионная'
						when 14 then ' целых и одна стотриллионная'
						when 15 then ' целых и одна квадрилионная'
						else ''
					end
				else 
					case @fractionalPartLen
						when 1 then ' целых и ' + @fractionalPart + ' десятых'
						when 2 then ' целых и ' + @fractionalPart + ' сотых'
						when 3 then ' целых и ' + @fractionalPart + ' тысячных'
						when 4 then ' целых и ' + @fractionalPart + ' десятитысячных'
						when 5 then ' целых и ' + @fractionalPart + ' стотысячных'
						when 6 then ' целых и ' + @fractionalPart + ' милионных'
						when 7 then ' целых и ' + @fractionalPart + ' десятимилионных'
						when 8 then ' целых и ' + @fractionalPart + ' стомилионных'
						when 9 then ' целых и ' + @fractionalPart + ' миллиардных'
						when 10 then ' целых и ' + @fractionalPart + ' десятимиллиардных'
						when 11 then ' целых и ' + @fractionalPart + ' стомиллиардных'
						when 12 then ' целых и ' + @fractionalPart + ' триллионных'
						when 13 then ' целых и ' + @fractionalPart + ' десятитриллионных'
						when 14 then ' целых и ' + @fractionalPart + ' стотриллионных'
						when 15 then ' целых и ' + @fractionalPart + ' квадрилионных'
						else ''
					end
				
			end

	return @return;
end
go


Пример:

select t1.num, dbo.fn_NumberToCursive_Decimal(t1.num)
from
(
	select 4517121121289.454 num
	union select 451712112128349.5454054540489001 num
	union select 4514070 num
	union select 551381.001 num
	union select 751062.454 num
	union select 45174583.4 num
	union select 153020.78564 num
	union select 4531002735.45 num
	union select 7981912.1 num
) t1
30 янв 17, 17:35    [20163050]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
Mairos
Member

Откуда:
Сообщений: 555
MaxusPerfectus, здорово. Пока только один косяк нашёл - пропускает значимые нули между цифрами в дробной части

-- Пример вызова
select t1.num, dbo.fn_NumberToCursive_Decimal(t1.num)
from
(
	 select 62.405 num
	
) t1


Результат "шестьдесят два целых и сорок пять тысячных"
31 янв 17, 14:05    [20166091]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 3175
iap
Александра77
есть десятки функций, преобразования цифры в строку
Какой именно цифры?


всех!
31 янв 17, 18:08    [20167242]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
MSSQLuserK1
Member

Откуда:
Сообщений: 14
Всем спасибо!) Пока вопрос временно снялся)
6 фев 17, 17:48    [20185891]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: И все же число прописью, как?  [new]
Евгенич
Member

Откуда:
Сообщений: 267
Mairos
MaxusPerfectus, здорово. Пока только один косяк нашёл - пропускает значимые нули между цифрами в дробной части

-- Пример вызова
select t1.num, dbo.fn_NumberToCursive_Decimal(t1.num)
from
(
	 select 62.405 num
	
) t1


Результат "шестьдесят два целых и сорок пять тысячных"




Не нашли почему?
12 авг 19, 09:15    [21946796]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
Посетитель
Member

Откуда:
Сообщений: 1384
Евгенич
Mairos
MaxusPerfectus, здорово. Пока только один косяк нашёл - пропускает значимые нули между цифрами в дробной части

-- Пример вызова
select t1.num, dbo.fn_NumberToCursive_Decimal(t1.num)
from
(
	 select 62.405 num
	
) t1



Результат "шестьдесят два целых и сорок пять тысячных"




Не нашли почему?


declare
		@fractionalPartOfNumber bigint = 
			cast(replace(cast(cast(@num % 1 * 1000000000000000 as bigint) as varchar(100)), '0', '') as bigint)

не?
12 авг 19, 09:22    [21946804]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
Евгенич
Member

Откуда:
Сообщений: 267
Посетитель
Евгенич
пропущено...




Не нашли почему?


declare
		@fractionalPartOfNumber bigint = 
			cast(replace(cast(cast(@num % 1 * 1000000000000000 as bigint) as varchar(100)), '0', '') as bigint)

не?


Как поправить?
13 авг 19, 12:55    [21947991]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
Gator
Member

Откуда: Москва
Сообщений: 14978
Клопов подавить трудно?

Вот потом маяться с падежами придётся.
13 авг 19, 13:06    [21948010]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
Евгенич
Member

Откуда:
Сообщений: 267
Евгенич
Посетитель
пропущено...


declare
		@fractionalPartOfNumber bigint = 
			cast(replace(cast(cast(@num % 1 * 1000000000000000 as bigint) as varchar(100)), '0', '') as bigint)

не?


Как поправить?


Сделал так:
@fractionalPartOfNumber bigint = 
			cast(replace(rtrim(replace(cast(cast(@num % 1 * 1000000000000000 as bigint) as varchar(100)), '0', ' ')),' ','0') as bigint)
13 авг 19, 13:31    [21948051]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
Khrupchik Eugeny
Member

Откуда:
Сообщений: 37
Евгенич,
SELECT n [ЧислоПрописью] from
(SELECT n1000.n + n100.n + case when n10.n = ' десять' and n1.n != ''
										then
										case n1.n when ' два'    then ' две'
											  when ' четыре' then ' четыр'
										 else n1.n end
										+ 'надцать'
										else n10.n + n1.n
										END [n]
		,n1.c + n10.c + n100.c + n1000.c [c]
FROM (VALUES('',0),(' сто',100),(' двести',200),(' триста',300),(' четыреста',400),(' пятьсот',500),(' шестьсот',600),(' семьсот',700),(' восемьсот',800),(' девятьсот',900)) n100(n,c), 
	(VALUES('',0),(' один',1),(' два',2),(' три',3),(' четыре',4),(' пять',5),(' шесть',6),(' семь',7),(' восемь',8),(' девять',9)) n1(n,c),
	(VALUES('',0),(' десять',10),(' двадцать',20),(' тридцать',30),(' сорок',40),(' пятьдесят',50),(' шестьдесят',60),(' семьдесят',70),(' восемьдесят',80),(' девяносто',90)) n10(n,c),
	(VALUES('',0),(' одна тысяча',1000),(' две тысячи',2000),(' три тысячи',3000),(' четыре тысячи',4000),(' пять тысяч',5000),(' шесть тысяч',6000),(' семь тысяч',7000),(' восемь тысяч',8000),(' девять тысяч',9000)) n1000(n,c)
	) a
	WHERE c = 5234 --сюда написать число которое надо прописью
22 авг 19, 14:51    [21955577]     Ответить | Цитировать Сообщить модератору
 Re: И все же число прописью, как?  [new]
komrad
Member

Откуда: Msk -> Utrecht
Сообщений: 5050
Khrupchik Eugeny,

WHERE c = 15


" пятьнадцать"
22 авг 19, 16:10    [21955680]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить