order clause for varchar ranges - sql

I currently have a column in db with few ranges storaged as varchar, such as:
0-499
1000-1199
500-999
How do I order these ranges like the following:
0-499
500-999
1000-1199
Thanks in advance

If you want to be tricky, you can do:
order by cast(replace(col, '-', '.') as decimal(30, 15))
This replaces the hyphen with a decimal point, converts to a numeric value, and uses that for sorting. This should work in just about any database.
This is not perfect, because it does not really order by the second number of the range correctly. But the first number would need to exactly match (and for some reason, that seems unlikely to me base on your sample data).

Order by the characters before the hyphen, converted to an integer.

You can useorder by clause with left() function :
order by cast(left(n, charindex('-', n)-1) as int);
However, the preceding order by cluase has int conversation, if you have decimal value before hyphen then use decimal instead

if these are the only values:
order by
case varcharcol when '0-100' then 1
when '500-1000' then 2
when '1000-1199' then 3
end

create table #temp1(id int,range varchar(50))
insert into #temp1(id,range)
values (1,'0-499'),(2,'1000-1199'),(3,'500-999')
select * from #temp1 order by cast(replace(range, '-', '.') as decimal(30, 15))
id range
1 0-499
3 500-999
2 1000-1199
select * from #temp1 order by cast (substring(range,0,charindex('-',range)) as int)
id range
1 0-499
3 500-999
2 1000-1199

Related

How to round multiple numeric columns to 2 digits in sql?

Say if I need to round multiple numbers to 2 digits now, but I don't want to repeat using round(..., 2) or format(...).
Is there any method to set up the float numbers with 2 digits globally?
select cast(float_column as decimal(10,2))
from your_table
Declare the column or variable of type numeric(18, 2)
You can also use with the CONVERT function
select CONVERT(numeric(18, 2) , 5.54722)

Problems with relational operators in a varchar field in sqlite

I have this syntax sql who should pick up all the records in the table where the 'stock_ quantity' (Varchar Column) column is less than the 'minimum_amount' (Varchar Column) column:
SELECT * FROM fazerem_xius WHERE stock_quantity < minimum_amount ORDER
BY name_products ASC
My syntax have a problem, if the column 'stock_quantity' stores the value 10, and column 'minimum_amount' stores the value 3, This record has been returned by the database, why is this happening and how to solve this type of problem?
Convert the string to a number before comparing. For instance with a mathematical operation
SELECT * FROM fazerem_xius
WHERE stock_quantity * 1 < minimum_amount * 1
ORDER BY name_products ASC
It's because string values are compared alphabetically. When you compare the string 10 to the string 3, SQLite checks the first characters first. 1 is before 3 in the alphabet, that's why the result of '10' < '3' is true.
Use CAST() to cast them to numbers:
SELECT * FROM fazerem_xius WHERE CAST(stock_quantity AS INTEGER) < CAST(minimum_amount AS INTEGER) ORDER BY name_products ASC

DB2 SQL Convert Decimal to Character with Padded Zeros

How can I convert my DECIMAL(11) field from 12345678 to a character value of 00012345678?
Only use the DIGITS function, because this verifies the length of the field numeric or decimal, etc and completes with zeros to the left when is necessary.
SELECT DIGITS(FIELD) FROM ...
The length of the resulting string is always:
5 if the argument is a small integer
10 if the argument is a large integer
19 if the argument is a big integer
Based on your comment in #Mr Fuzzy Botton's answer, I'm guessing you're on DB2 for i, which does not have the LPAD function. You could instead use a combination of the REPEAT and RIGHTfunctions:
SELECT RIGHT(REPEAT('0', 11) || LTRIM(CHAR(your_field)), 11)
FROM your_table
Using http://pic.dhe.ibm.com/infocenter/dzichelp/v2r2/topic/com.ibm.db2.doc.sqlref/castsp.htm for details on CAST
and http://pic.dhe.ibm.com/infocenter/dzichelp/v2r2/topic/com.ibm.db2z10.doc.sqlref/src/tpc/db2z_scalarfunctionsintro.htm for string functions,
I assume this should do the trick -
SELECT LPAD( CAST(FIELD AS CHAR(11)) ,11,'0') AS PADDEDFIELD
Don't know if you've worked it out, however try this:
SELECT LPAD( DIGITS( fieldName ), 11, '0') ) as paddedFieldName FROM yourTable
The LPAD is the left padding, but the DIGITS function was the only way I got DB2 to treat the numeric value like a string.
My LeftPad function without LeftPad function
REPEAT('0', 4-length(MY_COLUMN_VALUE))||CHAR(MY_COLUMN_VALUE) as NEW_COLUMN
MY_COLUMN_VALUE NEW_COLUMN
1 0004
23 0023
testing ...
SELECT '32' MY_VALUE, REPEAT('0', 4-length('23'))||CHAR('23') as LEFTPAB_MY_VALUE FROM sysibm.sysdummy1
If this is DB2 for i, and myColumn data type is DECIMAL with precision (11) and scale (0), then:
SELECT digits( myColumn ) FROM sysibm.sysdummy1
will return:
....+....1.
DIGITS
00001234567
Changing the number of leading zeros could be done in many ways. CASTing to a different precision before using DIGITS() is one way.
SELECT SUBSTRING(
CHAR(100000000000+fieldName),
2,11
) as paddedFieldName
FROM yourTable
I only wanted to define my field once in the select statement so the above worked for me and is tidy
I just went the other direction: cast(field as int)
Try this for your field x:
substr(digits(x), 33 - length(x), length(x) )
From Numeric 8,0 (datenumfld=20170101) to 01/01/2017 This works for me:
DATE(TO_DATE(CHAR(datenumfld), 'YYYYMMDD')) as YourDate

convert varchar(8) values and use ASC in T-SQL

I have a data in the table in the form below and it is in varchar(8) datatype
Total
100
101
104.5
88
1038
64
108.3
10872
900
I like to use ASC in T-sql so that I can display it into ascending order, however I
cannot do it as it is in varchar(8) form
For example
select Total from
Table A
Order by Total ASC
How to first add these values into Temporary temp table?
and How to convert this varchar(8) values and into what? so that
you can display them in ASC or ascending order using T-SQL query?
Anyone?
You could cast the value like this.
SELECT
Total
FROM Table A
ORDER BY CAST(Total AS FLOAT) ASC
You may lose data converting back to float.
So here is a varchar based sort.
DECLARE #badDesign TABLE (floatcol varchar(8) NOT NULL);
INSERT #badDesign VALUES ('100'),('101'),('104.5'),('88'),('1038'),('64'),('108.3'),('10872'),('900'),('108'), ('108.32'), ('108.4')
SELECT *
FROM #badDesign
ORDER BY
RIGHT('00000000' +
CASE
WHEN CHARINDEX('.', floatcol) = 0 THEN floatcol
ELSE LEFT(floatcol, CHARINDEX('.', floatcol)-1)
END
, 8),
CASE
WHEN CHARINDEX('.', floatcol) = 0 THEN '.0'
ELSE SUBSTRING(floatcol, CHARINDEX('.', floatcol)+1, 8)
END
The values from your example looks like float numbers. So
1) Since they all have no more than 8 digits, you can cast it to float(53) (it has about 15 decimal digits precision) without loss of data. Or to decimal(15,7) to be completely sure.
2) Generally it's strange to store float values as strings in the database.
Use CAST or CONVERT functions, e.g.:
select Total from
Table A
Order by CAST(Total as float) ASC
Reference: http://msdn.microsoft.com/en-us/library/ms187928.aspx
Unless you want to keep the converted values, you don't need to store it in a temporary table. Just convert them for the sorting:
select Total
from [Table A]
order by cast(Total as float)
(Ascending is the default way to sort, so you don't have to specify that.)

Problem with max() in sql server

I have alphanumeric values like. XYZ1,XYZ2......XYZ11, XYZ12 and so on, now I want to select only the Max numeric value, i.e. 12 here.
I tried-
select max(REPLACE(ID,'XYZ','')) from myTable;
but this is returning 9. why?
Try converting to INT before max
select max(cast(REPLACE(ID,'XYZ','') as int)) from myTable;
It's still treating your value as a string instead of a number. Try:
select max(CAST(REPLACE(ID,'XYZ','') AS INT) from myTable;
Because you're still comparing strings. The fact that they contain only numeric digits doesn't mean that they're not strings. You need to convert them:
SELECT MAX(CAST(REPLACE(id, 'XYZ', '') AS INT)) FROM My_Table
Another method is
select max(REPLACE(ID,'XYZ','')*1) from myTable