#### Introduction:

As part of the blog series TSQL - Solve it YOUR Way, today we will tackle a numeric parsing question.  While past topics include solutions that vary from 15-150 lines of TSQL code, all of today's solutions will be very short.  A question was recently posted in the MSDN forums asking how to retrieve the digits after the decimal for a numeric data type.  Off the top of our heads, many people can probably come up with a few solutions.  After sending the question out to the blog series contributors, we came up with ten solutions that highlight creative parsing solutions and some less known tips and tricks within T-SQL.

Topic:  Given a numeric value, return the digits after the decimal (ex:  3.142 returns 142)

#### Solutions - provided by Tom Cooper, Olaf Helper, Kent Waldrop, Jingyang Li, & Steven Wang

Code Snippet
1. -- Test data
2. Declare @Test Table(Foo decimal(9,3));
3. Insert @Test(Foo) Values (1.479), (2.000), (5.123);
4.
5. -- Solution 1:  ParseName
6. Select Foo, ParseName(Foo, 1) From @Test;
7.
8. -- Solution 2:  Modulo / Absolute Value
9. SELECT SUBSTRING(CONVERT(varchar(30), ABS(Foo) % 1), 3, 30) AS Result FROM @Test
10.
11. -- Solution 3:  Slightly modified version using modulo.  Note:  This solution returns '0' for input 2.000, whereas others return '000'
12. select Foo, cast(sign(Foo) * 1000 * (Foo % 1) as integer
13.   ) as decimal_Part
14. from @test
15.
16. -- Solution 4:  Reverse / Floor solution
17. SELECT REVERSE(CAST(FLOOR(REVERSE(ABS(Foo))) AS bigint)) from @Test
18.
19. -- Solution 5:  Use the original number minus an integer converted from the original number to an integer and then convert the decimal number to a varchar (50) to use the STUFF function to remove the '0.' part from the decimal number.
20. SELECT Stuff(Cast(Foo - Cast(Foo AS INT) AS VARCHAR(50)), 1, 2, '') from @Test
21.
22. -- Solution 6:  Remove the "0." part from the above calculation with a substring function
23. SELECT Substring(Cast(Foo - Cast(Foo AS INT) AS VARCHAR(50)), 3, Len(Foo)) from @Test
24.
25. -- Solution 7:  Use right function to remove the leading "0." from the string
26. SELECT RIGHT(Cast(Foo - Cast(Foo AS INT) AS VARCHAR(50)), Len(Cast(Foo - Cast(Foo AS INT) AS VARCHAR(50))) - 2) from @Test
27.
28. -- Solution 8:  Find the . position using charindex and stuff everything before decimal
29.   SELECT Stuff(Foo, 1, Charindex('.', Foo), '')from @Test
30.
31. -- Solution 9
32. SELECT Stuff(Foo, 1, Charindex(0X2E, Cast(Ltrim(Foo) AS VARBINARY(50)), 1), '') from @Test
33.
34. -- Solution 10:  CAST the string as an XML type and retrieve the value from the XML node
35. SELECT Cast (N'<root><row>' + Replace(Foo, '.', '</row><row>') + '</row></root>' AS XML).value('(/root/row)[2]', 'nvarchar(50)') from @Test

#### Conclusion:

It is very common to encounter situations where parsing is required in some capacity.  The solutions presented above cover common parsing techniques such as SUBSTRING and PARSENAME, but also leverage other constructs such as STUFF, REVERSE, Modulo, and others in creative ways.  I hope that you are able to learn a lot by trying out the problem yourself and then reading through the additional solutions.

Special thanks to Tom, Olaf, Jingyang, Steven, and Kent for their valuable forums contribution and for contributing to this series!

Hope that helps,
Sam Lester (MSFT)