Convert negative data into positive data in SQL Server - sql

The current data of the table is:
a b
---------
-1 5
-11 2
-5 32
My request is to convert every data into a positive value.
Unfortunately, I forgot the name of the built-in function of SQL Server that enables to convert.

You are thinking in the function ABS, that gives you the absolute value of numeric data.
SELECT ABS(a) AS AbsoluteA, ABS(b) AS AbsoluteB
FROM YourTable

The best solution is: from positive to negative or from negative to positive
For negative:
SELECT ABS(a) * -1 AS AbsoluteA, ABS(b) * -1 AS AbsoluteB
FROM YourTable
For positive:
SELECT ABS(a) AS AbsoluteA, ABS(b) AS AbsoluteB
FROM YourTable

UPDATE mytbl
SET a = ABS(a)
where a < 0

Use the absolute value function ABS. The syntax is
ABS ( numeric_expression )

An easy and straightforward solution using the CASE function:
SELECT CASE WHEN ( a > 0 ) THEN (a*-1) ELSE (a*-1) END AS NegativeA,
CASE WHEN ( b > 0 ) THEN (b*-1) ELSE (b*-1) END AS PositiveB
FROM YourTableName

Update all negatives to positive
UPDATE my_table
SET value = ABS(value)
WHERE value < 0
Get all the negative
SELECT value FROM my_table
WHERE value < 0
Get all the negatives and convert them to positive
SELECT ABS(value) FROM my_table
WHERE value < 0

Related

SQL query to get a result divided by 2

Given a table with column like city and cityId,Adderesses. How would i write a query that gives a list cities where cityID is only even numbers. Plz explain in details.
Use the modulo operator
select * from your_table
where mod(cityID, 2) = 0
You can detect whether a number is even with the module operator (%), which gives the remainder after division by 2:
select * from your_table where cityID % 2= 0
The above query will give all the rows in which the cityID is divisible by 2
If you are interested in mod then it would be
select 6%2 -- results for this is 0
if you would want to select a number divided by 2 it will always return 0 for the perfect devisors.
if want the division the use the normal / operator as below
eg select 6/3
I used a slightly different approach. this is an event if you want a result of a zero or 1 if perfect divisor and zero otherwise
So my script is something like this
select case when #value<2 then 0 when #value%2 =0 then 1 else 0 end as myresult;
An example is as below for validating numbers between 1 and 20. You could amend it to fit your purpose
begin
declare #a int,#b int
set #a=1;
set #b = 20
while #a<=#b
begin
declare #value int
set #value =#a
select #value as myval, case when #value<2 then 0 when #value%2 =0 then 1 else 0 end
as myresult;
set #a=#a+1;
end
end

SQL Server : SUM () for only numeric values, ignoring Varchar values

I need some help as I am learning SQL so I am at a beginner level. I am using SQL Server 2008 R2.
My question is: I want to (add) sum up a column that have mix values of varchar and decimal. I want to ignore the varchar values and sum only decimal. My column is like this:
Column1
-------
0.1
Z
0.4
2.1
2.1
Z
And I need the sum that is in this case it should be: 4.7
I tried using CASE but I failed to solve it
SELECT
SUM(CASE
WHEN ISNUMERIC(Column1) = 1
THEN .(if true how i add them?).
ELSE .(and if false how i ignore them?).
END) AS Total
FROM
TABLE_Name
I am not good in explaning things, but I hope you can understand me what I am trying to do.
If this question is already answered please give me directions to that question and my appologise for that.. Many thanks in advance :)
Simply use WHERE clause with CAST:
SELECT SUM(Cast(Column1 as numeric(10,2))) as Total
FROM TABLE_Name
Where IsNumeric(Column1) = 1
Result:
TOTAL
4.7
Sample result in SQL Fiddle.
EDIT:
As #funkwurm pointed out, the column has a chance to have the value '.' (dot):
SELECT SUM(Cast(Column1 as numeric(10,2))) as Total
FROM TABLE_Name
Where IsNumeric(Column1 + 'e0') = 1
Fiddle.
You can "ignore" a row by adding 0.
SELECT
SUM(
CASE
WHEN ISNUMERIC(Column1)=1 THEN CONVERT(DECIMAL(10,5), Column1) --add the value to the sum
ELSE 0 --add 0 (i.e. ignore it)
END)
AS Total
FROM
TABLE_Name
try
select sum(case when isnumeric(cast(Column1 as decimal))
then cast(column1 as decimal) else 0 end) as total from table
assuming your field is varchar type
Why not using TRY_CONVERT:
SELECT SUM(TRY_CONVERT(float,Column1) AS Total
FROM TABLE_Name
Shortest query and easy to read! TRY_CONVERT returns NULL if conversion fails (e.g. if there are text values in Column1)
This Functions exists since SQL Server 2012 (i think).
#Jim Chen:
Isnumeric is a bit tricky a this point! In your solution there would be a problem if the value '-' or '+' is inside a Column:
SELECT ISNUMERIC('+') --returns TRUE!
SELECT ISNUMERIC('-') --returns TRUE!
==> SUM will FAIL!

How do I change a field to a negative based on another field's value in SQL

With the below statement I would like amount to be negative if [Invoice_Type_Code] = 'c', and if is not then it is positive.
SELECT [Invoice_Amount]
FROM [Forefront].[dbo].[VN_GL_DISTRIBUTION_HEADER_MC]
WHERE [Vendor_Code] =' UnitedEL' and
[Date_List1] > '2011-12-31' and
[Date_List1] < '2012-02-01' and
[Company_Code] = 'tmg'
Depending on your RDBMS, using CASE could work -- most RDBMS should support it:
SELECT CASE WHEN Invoice_Type_Code = 'C' THEN -1 ELSE 1 END * Invoice_Amount
FROM [Forefront].[dbo].[VN_GL_DISTRIBUTION_HEADER_MC]
where [Vendor_Code] =' UnitedEL' and
[Date_List1] > '2011-12-31' and [Date_List1] < '2012-02-01' and
[Company_Code] = 'tmg'
This assumes all Invoice_Amounts are positive. If they aren't positive and you still need negative values, use the ABS function and alter your case statement slightly.
Here is the Fiddle.
Good luck.

Specify order of (T)SQL execution

I have seen similar questions asked elsewhere on this site, but more in the context of optimization.
I am having an issue with the order of execution of the conditions in a WHERE clause. I have a field which stores codes, most of which are numeric but some of which contain non-numeric characters. I need to do some operations on the numeric codes which will cause errors if attempted on non-numeric strings. I am trying to do something like
WHERE isnumeric(code) = 1
AND CAST(code AS integer) % 2 = 1
Is there any way to make sure that the isnumeric() executes first? If it doesn't, I get an error...
Thanks in advance!
The only place order of evaluation is guaranteed is CASE
WHERE
CASE WHEN isnumeric(code) = 1
THEN CAST(code AS integer) % 2
END = 1
Also just because it passes the isnumeric test doesn't guarantee that it will successfully cast to an integer.
SELECT ISNUMERIC('$') /*Returns 1*/
SELECT CAST('$' AS INTEGER) /*Fails*/
Depending upon your needs you may find these alternatives preferable.
Why not simply do it using LIKE?:
Where Code Not Like '%[^0-9]%'
Btw, either using my solution or using IsNumeric, there are some edge cases which might lead one to using a UDF such as 1,234,567 where IsNumeric will return 1 but Cast will throw an exception.
Why not use a CASE statement to say something like:
WHERE
CASE WHEN isnumeric(code) = 1
THEN CAST(code AS int) % 2 = 1
ELSE /* What ever else if not numeric */ END
You could do it in a case statement in the select clause, then limit by the value in an outer select
select * from (
select
case when isNum = 1 then CAST(code AS integer) % 2 else 0 end as castVal
from (
select
Case when isnumeric(code) = 1 then 1 else 0 end as isNum
from table) t
) t2
where castval = 1

Decimal number, to_char, and Oracle

I am trying to figure out a format spec of to_char() that would give me the following result.
to_char(0.1, '[FORMAT_SPEC]')
gives 0.1 and:
to_char(1, '[FORMAT_SPEC]')
gives 1.
I've tried the following solutions:
to_char(0.1)
gives '.1'.
to_char(0.1, 'FM0.099')
gives 0.1, which is okay, however:
to_char(1, 'FM0.099')
gives 1.0, which is not okay.
Do you have any suggestions?
The precision returned needs to be consistent, so the only alternative is to use DECODE or CASE statements to conditionally return what you need:
CASE
WHEN INSTR(TO_CHAR(t.col), '.') = 0 THEN TO_CHAR(t.col)
ELSE TO_CHAR(t.col, 'FM0.099')
END
The example isn't great - it's not clear if your data will have values like 1.000 or values above one/etc.
EDIT Michael-O (2013-06-25): For those who need it idiot-proof, you may try:
case
when instr(to_char(<col>), (select to_char(0, 'FMD') from dual)) = 0
then to_char(<col>)
else to_char(<col>, 'FM999990D999')
end
It automatically observes the decimal separator. Adapt the the secodn format modal to your number size.
I just use this:
TRIM('.' FROM TO_CHAR(x, 'FM99990.999'))
Don't happen to have an Oracle instance handy to test this in, but I'd think that
TO_CHAR(1, 'FM0.999')
oughta do it.
Not sure what range of values you will be expecting but you could case out values < 1 versus those >= 1. Otherwise either the trailing 0 or the decimal is going to get in your way:
select val,
case when val < 1 then to_char(val, 'FM99990.9')
else to_char(val, 'FM99999')
end fmt
from (select 0.1 val from dual union all
select 1 from dual
)
/
VAL FMT
---------- --------
.1 0.1
1 1