I have a column in my sql table. I am wondering how can I add leading zero to my column when my column's value is less than 10? So for example:
number result
1 -> 01
2 -> 02
3 -> 03
4 -> 04
10 -> 10
format(number,'00')
Version >= 2012
You can use RIGHT:
SELECT RIGHT('0' + CAST(Number AS VARCHAR(2)), 2) FROM tbl
For Numbers with length > 2, you use a CASE expression:
SELECT
CASE
WHEN Number BETWEEN 0 AND 99
THEN RIGHT('0' + CAST(Number AS VARCHAR(2)), 2)
ELSE
CAST(Number AS VARCHAR(10))
END
FROM tbl
Felix's solution is great, unless you have numbers above 100 in your table, in which case, try using a case statement instead:
Select case when Number between 1 and 9
then '0' else '' end + cast(number as varchar(3))
And yet one more solution:
SELECT REPLACE(STR(#YourNumber,2),' ','0');
I prefer this, as other approaches might lead to random results in case of numbers which are wider than the count of digits you've specified:
But it will not deal with negativ numbers...
DECLARE #YourNumber INT=123;
SELECT REPLACE(STR(#YourNumber,5),' ', '0') --pad to five digits
,REPLACE(STR(#YourNumber,3),' ', '0') --pad to 3 digits
,REPLACE(STR(#YourNumber,2),' ', '0'); --123 is wider than 2 digits...
The result
00123
123
**
another method,
select case when number <10 then replicate('0',1)+cast(number as varchar)
else cast(number as varchar) end
In another method, you can Replace 10 to 2.
declare #ID int =32123;
substring('000000000',1,10-len(cast(#ID as varchar(10)))) + cast(#Id as varchar(10))
Result:
0000032123
Related
I have a column of financial data that shows. Some figures are positive and some are negative.
Is it possible to change a number like -945 to (945) this is on SQL Server 2005.
The following expression should work for most cases:
SELECT num, CASE
WHEN num < 0 THEN '(' + CAST(-num AS VARCHAR(11)) + ')'
ELSE CAST(num AS VARCHAR(11))
END AS frmtd
FROM (
SELECT 0 AS num UNION ALL
SELECT 945 UNION ALL
SELECT -945
) tests
There is an SQL function called ABS() that basically changes negative and positive numbers to just their relative value from 0, meaning it removes the minus but doesn't affect positive values.
You can find out more about it here
You can also try using Replace function in Sql Server as shown below.
When value is in (-) ve.
Select CAST(REPLACE(CAST(-945 as Varchar(4)), '-', '') as Int)
When value is already in (+) ve.
Select CAST(REPLACE(CAST(945 as Varchar(4)), '-', '') as Int)
The output in both case will be: 945
In a certain SQL table I'm working on, there's a column that contains data formatted like:
"year-text~year-text~year-text~year-text~year-text~year-text~year-text~" and so on and so forth.
(year is in 'yyyy' format)
(for example):
"2012-10000~2013-5000~2014-500~2015-50000~2016-100~"
How, using SQL might I extract, say, the value "50000" based on having the year, "2015"
Things to note/clarify:
The "-" and "~" characters can be trusted as delimiters. That is, they do not exist within any of the values or, of course, the years.
No year exists without a value. In other words, if the value becomes blank, the year is stripped out, as well (In other words, the stored string will never have an "-" and a "~" right next to each other, such as 2016 in the string "2015-200~2016-~2014-1000", for example).
The years in the string may not be in chronological order from left to right.
There could be virtually any number of years (each with a value) in the string or, indeed, none, at all. If no year/value pair exists for the column, the value becomes NULL
Please note that after each value for each year the character "~" is applied even if it is the last year/value pair. Any string value that is not NULL will therefore always end with a "~".
Perhaps this can help
With the aid of a parser and cross apply
Declare #String varchar(max) = '012-10000~2013-5000~2014-500~2015-50000~2016-100~'
Select A.*
,B.*
From [dbo].[udf-Str-Parse](#String,'~') A
Cross Apply (Select Val1=max(IIF(Key_PS=1,Key_Value,NULL))
,Val2=max(IIF(Key_PS=2,Key_Value,NULL))
From [dbo].[udf-Str-Parse](A.Key_Value,'-')) B
Where A.Key_Value<>''
Returns
Key_PS Key_Value Val1 Val2
1 012-10000 012 10000
2 2013-5000 2013 5000
3 2014-500 2014 500
4 2015-50000 2015 50000
5 2016-100 2016 100
My Parser if needed
CREATE FUNCTION [dbo].[udf-Str-Parse] (#String varchar(max),#Delimeter varchar(10))
--Usage: Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
-- Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
Returns #ReturnTable Table (Key_PS int IDENTITY(1,1), Key_Value varchar(max))
As
Begin
Declare #XML xml;Set #XML = Cast('<x>' + Replace(#String,#Delimeter,'</x><x>')+'</x>' as XML)
Insert Into #ReturnTable Select ltrim(rtrim(String.value('.', 'varchar(max)'))) FROM #XML.nodes('x') as T(String)
Return
End
Here is an option which uses SUBSTRING and CHARINDEX to get the job done:
SUBSTRING(col,
CHARINDEX('2015', col) + 5,
CHARINDEX('~', col, CHARINDEX('2015', col) + 5) - (CHARINDEX('2015', col) + 5))
In the sample input
2012-10000~2013-5000~2014-500~2015-50000~2016-100~
CHARINDEX('2015', col) + 5 would start at the 5 in the number 50000 after the occurrence of 2015.
The term
CHARINDEX('~', col, CHARINDEX('2015', col) + 5) - (CHARINDEX('2015', col) + 5)
yields the length of the number 50000, which in this case would be 5.
you can use substr and charindex
select substr( charindex( 'your_val', your_column) + length('your__val') +1, 4);
in your case
select substr( charindex( '2016', your_column) + length('2016') +1, 4);
I need some help with a sql transformation. This part of query that I have been provided with:
'$' + replace(cast((CAST(p.Price1 AS decimal(10,2)) * cast(isnull(p.Multiplier,1) as decimal(10,2))) as varchar), '.0000', '')
Basically, it ends up being a varchar that looks like this: $26980
I need to insert a comma at the thousand and million mark (if applicable). So in this instance, $26,980
What's the easiest way to do that without having to rewrite the whole thing?
Do it on the client side. Having said that, this example should show you the way.
with p(price1, multiplier) as (select 1234.5, 10)
select '$' + replace(cast((CAST(p.Price1 AS decimal(10,2)) * cast(isnull(p.Multiplier,1) as decimal(10,2))) as varchar), '.0000', ''),
'$' + parsename(convert(varchar,cast(p.price1*isnull(p.Multiplier,1) as money),1),2)
from p
The key is in the last expression
'$' + parsename(convert(varchar,cast(p.price1*isnull(p.Multiplier,1) as money),1),2)
Note: if p.price1 is of a higher precision than decimal(10,2), then you may have to cast it in the expression as well to produce a faithful translation since the original CAST(p.Priced1 as decimal(10,2)) will be performing rounding.
If you really must do it in TSQL you can use CONVERT(), but this sort of thing really doesn't belong in the database:
declare #m money = 12345678
-- with decimal places
select '$' + convert(varchar, #m, 1)
-- without decimal places
select '$' + replace(convert(varchar, #m, 1), '.00', '')
You could turn this into a function, it only goes 50 characters back.
DECLARE #input VARCHAR(50)
SELECT #input = '123123123.00'
SELECT #input = CASE WHEN CHARINDEX('.', #input) > offset +1
THEN STUFF(#input, CHARINDEX('.', #input) - offset, 0, ',')
ELSE #input END
FROM (SELECT 3 offset UNION SELECT 7 UNION SELECT 12 UNION SELECT 18 UNION SELECT 25 UNION SELECT 33 UNION SELECT 42) b
PRINT #input
The offset grows by +1 for each position, because it's assuming you've already inserted the commas for the previous positions.
I need help formatting numbers in a specific way.
If a number has three decimal places or less, I would like it to remain the same.
If a number has more than three significant figures, I would like all numbers after the third significant figure to be the fractional part of the number.
123 --> Stays the same
1234 --> 123.4
How can this be done?
EDIT:
1234567 --> 123.4567
I am on SQL 2007, wishing to UPDATE the value in the table. The value is stored as a numeric.
Here is a numeric solution:
UPDATE T SET NUM = NUM/POWER(10,FLOOR(LOG10(NUM))-2)
WHERE NUM>=1000
Or the SELECT statement:
SELECT NUM, CASE WHEN NUM<1000 THEN NUM
ELSE NUM/POWER(10,FLOOR(LOG10(NUM))-2)
END AS NewNUM
FROM T
Note that the exact results can vary depending on the data type of NUM. If it is a FLOAT field, it might round the last decimal if NUM gets too large. If it is of type NUMERIC, it will add zero's to the end. If DECIMAL, you need to be careful of the precision. Note that this applies to all the update solutions already mentioned.
This could work
SELECT
CASE WHEN Num > 999 THEN Num/10
ELSE
Num
END As Num
There could be a better way, but this is what I could think of
You could do this with strings.
CREATE TABLE T
( NUM NUMERIC(38,19) );
INSERT INTO T (NUM) VALUES ( 123456789 );
INSERT INTO T (NUM) VALUES ( 12345 );
INSERT INTO T (NUM) VALUES ( 123 );
INSERT INTO T (NUM) VALUES ( 1 );
SELECT CAST(
CASE WHEN NUM < 999 THEN CAST(FLOOR(NUM) AS VARCHAR)
ELSE SUBSTRING(CAST(NUM AS VARCHAR), 1, 3) + '.'
+ SUBSTRING(CAST(FLOOR(NUM) AS VARCHAR), 4, LEN(CAST(NUM AS VARCHAR)) - 3)
END AS NUMERIC(38, 19))
FROM T
UPDATE T
SET NUM = CAST(CASE WHEN NUM < 999 THEN CAST(FLOOR(NUM) AS VARCHAR)
ELSE SUBSTRING(CAST(NUM AS VARCHAR), 1, 3) + '.'
+ SUBSTRING(CAST(FLOOR(NUM) AS VARCHAR), 4, LEN(CAST(NUM AS VARCHAR)) - 3)
END AS NUMERIC(38, 19));
I've put a working example on SQLFiddle.
Assuming strings of only integer values:
SELECT CASE WHEN LEN(Num) <= 3 THEN Num
ELSE STUFF(Num,4,0,'.')
END
FROM (VALUES('1234567'),('123'),('1234'),('12')) t(Num) --some sample values
Result:
123.4567
123
123.4
12
I answered this on a cross-post elsewhere, but for completeness:
WITH n(r) AS (
SELECT 123 UNION ALL SELECT 1234 UNION ALL SELECT 1234567
)
SELECT LEFT(r, 3) + CASE
WHEN LEN(r) > 3 THEN '.' + SUBSTRING(RTRIM(r),4,38) ELSE '' END
FROM n;
I am trying to figure out a good way to return a string 'name' of a range in which a given number falls. Ranges are spans of 1000, so the first range is '0000-0999', the second is '1000-1999' etc. For example, given the number 1234, I want to return the literal string '1000-1999'.
It seems to me that I could maintain a reference table with these ranges, like this
--create & populate temp table with ranges
create table #ranges (st int,en int)
go
insert into #ranges values(0,999)
insert into #ranges values(1000,1999)
insert into #ranges values(2000,2999)
go
--example query
select replace(str(st,4),' ','0') + '-' + replace(str(en,4),' ','0') as TheStringIWant
from #ranges
where 1234 between st and en
...but it seems to me that the ranges should be able to be determined from the given number itself, and that I shouldn't need the (redundant) reference table (or, for that matter, a function) just for this.
It also seems to me that I should be able to figure this out with just a bit of brain power, except that I've just had 2 beers in quick succession this evening...
Another way;
select case when value / 1000 < 1
then '0000-0999'
else cast(value / 1000 * 1000 as varchar(16)) + '-' + cast(value / 1000 * 1000 + 999 as varchar(16))
end
You can use mathematical functions to avoid using the temp table:
SELECT 1234,
RIGHT('0000' + CAST(FLOOR(1234/1000.0) * 1000 AS VARCHAR(11)),4)
+ '-'
+ RIGHT('0000' + CAST( (FLOOR(1234/1000.0) * 1000) + 999 AS VARCHAR(11)),4)
In the shell, I can use integer-arithmetic to cut off the 234, and calculate the string with a simple formular, however it wouldn't produce 0000-0999 but 0-999 for the first 1000.
v=1234
echo $(((v/1000)*1000))-$(((v/1000)*1000+999))
1000-1999
I don't know how to adapt it to tsql - whether possible at all.
declare #range int;
set #range = 1000;
select replace(str(st,4),' ','0') + '-' +
replace(str(st + #range,4),' ','0') as TheStringIWant
from (
select st = v / #range * #range
from (select v = 1234) s
) s