Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I update a table to insert decimal points at a fixed position in numbers?

I am using Microsoft SQL Server 2014 and have a table with three columns and the field data type is Decimal(38,0).

I want to update each row of my table to insert a decimal point after the first two digits. For example, I want 123456 to become 12.3456. The numbers are different lengths; some are five digits, some are seven digits, etc.

My table is:

+-------------+-------+-------+
| ID          |   X   |   Y   |
+-------------+-------+-------+
| 1200        | 321121| 345000|
| 1201        | 564777| 4145  |
| 1202        | 4567  | 121444|
| 1203        | 12747 | 789887|
| 1204        | 489899| 124778|
+-------------+-------+-------+

And I want to change this to:

+-------------+--------+--------+
| ID          |   X    |   Y    |
+-------------+--------+--------+
| 1200        | 32.1121| 34.5000|
| 1201        | 56.4777| 41.45  |
| 1202        | 45.67  | 12.1444|
| 1203        | 12.747 | 78.9887|
| 1204        | 48.9899| 12.4778|
+-------------+--------+--------+

My code is:

Update [dbo].[UTM]
     SET [X] = STUFF([X],3,0,'.')
         [Y] = STUFF([X],3,0,'.')

And I tried this:

BEGIN
DECLARE @COUNT1 int;
DECLARE @COUNT2 int;
DECLARE @TEMP_X VARCHAR(255);
DECLARE @TEMP_Y VARCHAR(255);
DECLARE @TEMP_main VARCHAR(255);

SELECT @COUNT1 = COUNT(*) FROM [UTM];
SET @COUNT2 = 0;

    WHILE(@COUNT2<@COUNT1)
    BEGIN
        SET @TEMP_main = (SELECT [id] from [UTM] order by [id] desc offset @COUNT2 rows fetch next 1 rows only);
        SET @TEMP_X = (SELECT [X] from [UTM] order by [id] desc offset @COUNT2 rows fetch next 1 rows only);
        SET @TEMP_Y = (SELECT [Y] from [UTM] order by [id] desc offset @COUNT2 rows fetch next 1 rows only);

        UPDATE [dbo].[UTM]
           SET [X] = CONVERT(decimal(38,0),STUFF(@TEMP_X,3,0,'.'))
              ,[Y] = CONVERT(decimal(38,0),STUFF(@TEMP_Y,3,0,'.'))
           WHERE [id] = @TEMP_main;

        SET @COUNT2 = @COUNT2  +  1
    END

END
like image 339
Javad Abedi Avatar asked Feb 04 '19 12:02

Javad Abedi


People also ask

How can you set the decimal places in a number?

By using a button: Select the cells that you want to format. On the Home tab, click Increase Decimal or Decrease Decimal to show more or fewer digits after the decimal point.

How do you align a table with decimals in Word?

Double click at the ruler where you want your decimal point to be. You will then notice a decimal tab appears on the ruler. In the following “Tabs” dialog box, select “Decimal” under “Alignment” and make sure you select “1 None” under “Leader”. And then click “OK”.

How do you add a decimal in the middle of a number in Excel?

Click the File tab. Click on Options. In the Excel Options dialog box that opens up, click on the 'Advanced' option in the left pane. In the editing options, enable the setting – “Automatically insert or decimal point”

How do you insert a decimal value in a table in SQL?

The Basic syntax of Decimal data type in SQL Server Where, p stands for Precision, the total number of digits in the value, i.e. on both sides of the decimal point. s stands for Scale, number of digits after the decimal point.


3 Answers

This runs on an assumption from a previously deleted post (that you have negative number as well).

Firstly, as you're using a decimal(38,0) you can't store values with any kind of precision, thus you need to change the data type as well. This provides the results you appear to be looking for:

USE Sandbox;
GO

CREATE TABLE dbo.SampleTable (ID int,
                              X decimal(38,0),
                              Y decimal(38,0));
INSERT INTO dbo.SampleTable (ID,
                             X,
                             Y)
VALUES (1200,321121,345000), 
       (1201,564777,4145  ), 
       (1202,4567  ,121444), 
       (1203,12747 ,789887), 
       (1204,489899,124778),
       (1205,-32472,-27921);
GO
--Fix the datatype
ALTER TABLE dbo.SampleTable ALTER COLUMN X decimal(10,4); --Based on data provided, may need larger scale
ALTER TABLE dbo.SampleTable ALTER COLUMN Y decimal(10,4); --Based on data provided, may need larger scale
GO

--update the data
UPDATE dbo.SampleTable
SET X = STUFF(ABS(CONVERT(int,X)),3,0,'.') * CONVERT(decimal(10,4),CASE WHEN X < 0 THEN -1.0 ELSE 1.0 END),
    Y = STUFF(ABS(CONVERT(int,Y)),3,0,'.') * CONVERT(decimal(10,4),CASE WHEN Y < 0 THEN -1.0 ELSE 1.0 END);

SELECT *
FROM dbo.SampleTable;
GO

DROP TABLE dbo.SampleTable;

Note that you won't get a value like 41.45, but instead 41.4500. If you don't want to display trailing 0's you need to do the formatting in your presentation layer (otherwise you'd have to store the values as a varchar, and that's a very bad idea).

like image 107
Larnu Avatar answered Oct 21 '22 21:10

Larnu


Try the following update:

UPDATE UTM
SET
    X = CAST(X AS DECIMAL(10,2)) / POWER(10, LEN(CAST(ABS(X) AS VARCHAR(10)))-2),
    Y = CAST(Y AS DECIMAL(10,2)) / POWER(10, LEN(CAST(ABS(Y) AS VARCHAR(10)))-2);

The logic here is to divide each number by 10 to the power of the number's length minus 2. This works for both positive and negative numbers, because we use the number's absolute value for normalizing. Follow the link below for a running demo.

enter image description here

Demo

like image 45
Tim Biegeleisen Avatar answered Oct 21 '22 22:10

Tim Biegeleisen


Just do this in the update:

Update [dbo].[UTM]
     SET X = STUFF(CONVERT(VARCHAR(255), X), 3, 0, '.'),
         Y = STUFF(CONVERT(VARCHAR(255), X), 3, 0, '.');

The values are converted to strings, but the strings will be implicitly converted back to whatever type X and Y are. You may get an error if the types are not compatible.

If you have negative values, then you should include them in the same data. This is handled using case:

Update [dbo].[UTM]
     SET X = STUFF(CONVERT(VARCHAR(255), X), (CASE WHEN X < 0 THEN 4 ELSE 3 END), 0, '.'),
         Y = STUFF(CONVERT(VARCHAR(255), X), (CASE WHEN X < 0 THEN 4 ELSE 3 END), 0, '.');
like image 7
Gordon Linoff Avatar answered Oct 21 '22 21:10

Gordon Linoff