Counting spaces before and after a decimal point - sql

I have data set as a varchar(500), but I only know if it's numeric or character.
I need to count the max spaces of the length of a column AND the max spaces after a decimal point.
For Example:
ColumnA
1234.56789
123.4567890
would return 11 spaces total AND 7 spaces after the decimal.
It can be two separate queries.

SELECT len(ColumnA), len(columnA) - charIndex('.',ColumnA)
FROM theTable

SELECT LEN(ColumnA )
,CHARINDEX('.',REVERSE(ColumnA ))-1
FROM Table1
If a value has no decimal, the above will return -1 for the spaces after decimal, so you could use:
SELECT LEN(ColumnA)
,CASE WHEN ColumnA LIKE '%.%' THEN CHARINDEX('.',REVERSE(ColumnA))-1
ELSE 0
END
FROM Table1
Demo of both: SQL Fiddle
If you just wanted the MAX() then you'd just wrap the above in MAX():
SELECT MAX(LEN(ColumnA ))
,MAX(CHARINDEX('.',REVERSE(ColumnA ))-1)
FROM Table1

SELECT ColumnA, Len(ColumnA) As Total, LEN(SUBSTRING(ColumnA,CHARINDEX('.',ColumnA,LEN(ColumnA)) As Decimal
FROM TABLE

Related

Can't get a correct sort with SQL Server 2008

I have a table with returns such as 12X90, 12X120, 12X160, etc.
The numbers after the "X" are weights. I need to pad the weights only with leading zeros so that 90 become 090. A normal sort will put the 90 last instead of first, I need the list sorted correctly, by weight.
How can I achieve that?
Use charindex to get the number after X in the column and order by that number.
select * from tablename
order by cast(case when charindex('X',col) > 0 then substring(col,charindex('X',col)+1,len(col))
else col end as numeric)
If the string before X should also be considered for sorting, use
select * from tablename
order by
cast(case when charindex('X',col) > 0 then substring(col,1,charindex('X',col)-1)
else col end as numeric)
,cast(case when charindex('X',col) > 0 then substring(col,charindex('X',col)+1,len(col))
else col end as numeric)
Sample demo
use a cross apply
select
b.* from table t1
cross apply
(select replace(t.weight,'12x','') as replaced from table t2 where t2.weight=t1.weight) b
order by b.replaced

How to calculate an average in SQL excluding zeroes?

I want to calculate the average of a column of numbers, but i want to exclude the rows that have a zero in that column, is there any way this is possible?
The code i have is just a simple sum/count:
SELECT SUM(Column1)/Count(Column1) AS Average
FROM Table1
SELECT AVG(Column1) FROM Table1 WHERE Column1 <> 0
One approach is AVG() and CASE/NULLIF():
SELECT AVG(NULLIF(Column1, 0)) as Average
FROM table1;
Average ignores NULL values. This assumes that you want other aggregations; otherwise, the obvious choice is filtering.
Multiple roads lead to Rome...
select sum(Column1) / sum( case Column1
case 0 then 0 else 1
end )
from table1
SELECT AVG(column) FROM TABLE
where column **not like** '0%'

Sum all row exclude the negative numbers in Oracle Reports

I have one table with 10 rows. I want to sum the values in a particular column. But I want to exclude all the negative numbers.
How can I sum just the positive numbers and ignore the negative numbers?
This is my pictures example:
With your specifications,
Select sum(col)
from table
where col>0;
You can do something like
SELECT SUM( case when column_name > 0
then column_name
else 0
end ) sum_of_non_negative
FROM table_name
Select sum(col)
from table
where col>0
AND col not like '-%';

sql sum + varchar

I have varchar type column in my sql table(SQL 2008) for storing student marks. If I store only the marks I can calculate the sum of marks by casting the column to integer.
But I need to store Absent for absentees. And now, its showing error in that Absent when casting to integer and sum the value, after inserting Absent.
Is it possible to sum only the marks, and excluding the Absent?I tried like this
select sum(cast(Marks as integer))
from Results
group by Marks
No need to add Group by Clause.
No other columns in Select other than column used in Aggregate function then no need to have GROUP BY.
select sum(cast(Marks as integer))
from Results
where Marks <>'Absent'
You should use an integer column for Marks and you should have a column of its own for Absent.
To fix your current situation you can use a case statement.
select sum(case Marks when 'Absent' then 0 else Marks end)
use decode function as -
select sum(decode(Marks, 'Absent', 0, cast(Marks as integer)))
Assuming the absent is Absent in the column.
Try this -
select sum(IF(Marks = 'Absent', 0, cast(Marks as integer))) -- MySQL
select sum(decode(Marks, 'Absent', 0, cast(Marks as integer))) -- Oracle
from Results
group by Marks;
OR
select sum(cast(Marks as integer))
from Results
where Marks <> 'Absent'
group by Marks
select sum(cast(Marks as integer))
from Results
where Marks <> 'Absent'
Just add a where clause!
Maybe something like this?
select sum(cast(Marks as integer))
from Results
where Marks <> 'Absent'
Wow, my preferred solution in SQL Server would simply be:
select sum(case when isnumeric(Marks) = 1 then cast(Marks as Integer) end)
from Results
Or, equivalently:
select cast(Marks as Integer)
from Results
where isnumeric(Marks) = 1
The group by is unnecessary, unless you are trying to produce a histogram.
By the way, the above is still prone to error, because floating point numbers cannot safely be converted to integers. You might prefer:
select cast(sum(case when isnumeric(Marks) = 1 then cast(Marks as float) end) as int)
from Results

Select rows that contain both English and non-English characters

Ok so I have a column in a table in SQL Server.
Each records have a string (i.e. names)
SOME of the strings have English AND NON ENGLISH characters.
I have to select ONLY the records that have English AND NON English characters.
How do I go about doing that?
My try...
Select * from Table
Where Nameofthecolumn NOT LIKE '%[A-Z]%'
Go
This will give me EMPTY table.
I know for sure that there are at least two records that have english and non-english characters.
I need those two records as output.
I was trying to do
Select * from Table
Where Nameofthecolumn NOT LIKE '%[A-Z,a-z]%' AND Like '%[A-Z,a-z]%'
Go
but turns out you can use boolean with Like/Not Like.
Please guide me the right direction.
Thanks
How about reversing your search, e.g. find anything that doesn't match A-Z:
... WHERE col LIKE '%[^A-Z]%' AND col LIKE '%[A-Z]%';
If the collation is case insensitive you shouldn't need a-z, if it is case sensitive you could add the COLLATE clause. But you may want to filter out spaces, numbers and other non-alphanumerics that are expected.
Do you mean something like this?
select 1 as field1,'1' as field2 into #data
union all select 1,'abc'
union all select 2,'abc'
union all select 3,'999'
SELECT * FROM
(
select field1,field2
,MAX(CASE WHEN field2 NOT LIKE '%[A-Z,a-z]%' THEN 1 ELSE 0 END) OVER (PARTITION BY field1)
+ MAX(CASE WHEN field2 LIKE '%[A-Z,a-z]%' THEN 1 ELSE 0 END) OVER (PARTITION BY field1) as chars
FROM #data
) alias
WHERE chars =2