selecting rows depending on the first digit of an integer in a column - sql

Using SQL in PostgreSQL I need to select all the rows from my table called "crop" when the first digit of the integer numbers in column "field_id" is 7.
select *
from crop
where (left (field_id,1) = 7)

First, you know that the column is a number, so I would be inclined to explicitly convert it, no matter what you do:
where left(crop::text, 1) = '7'
where crop::text like '7%'
The conversion to text is simply to be explicit about what is happening and it makes it easier for Postgres to parse the query.
More importantly, if the value has a fixed number of digits, then I would suggest using a numeric range; something like this:
where crop >= 700000 and crop < 800000
This makes it easier for Postgres to use an index on the column.

Try with cast, like this:
select *
from crop
where cast(substring(cast(field_id as varchar(5)),1,1) as int) = 7
where 5 in varchar(5) you should put number how long is your integer.

Related

I am trying to compare two number using Sql query. for e.g 123.45 and 12345 are same if i ignore decimal so it should come in output

I am trying to compare two string using Sql query. for e.g In table A i have A123.45 and in table B i have A12345. this two string are same if i ignore decimal point so as a output i would want table A's value.
First, to avoid the XY problem, it's a little unclear to me why you'd want to do this in the first place - I'm not sure exactly why 123.45 should be equal to 12345. Definitely something to think about.
With that said, if you insist, you can do something like the following:
select case when replace(cast(floatingPointNumber as varchar(50)), '.', '') = cast(yourInteger as varchar(50)) then 1 else 0 end
from YourTable
Obviously, floatingPointNumber is a float and yourInteger is an integer.
I'm not sure what platform you're using since you didn't tag it but I wrote/tested this in SQL Server. You can do something similar in Oracle/MySQL if that's what you're using.
Basically, what this is doing is casting both the floating point number and the integer to strings, removing the decimal from the floating point number, and comparing them. If they're equal, it returns 1; otherwise it returns 0.

How to compare various VARCHAR as numbers in Oracle

I have a table with various number formats like:
2
3.44189
4,1
-0.0022
9.9E+37
1.9E-12
these are measurements in a varchar2 column and to each measurement there is a specification with upper and lower limit value (in same format),
so what i want are measurements in between these borders
SELECT VALUE, LOW, HIGH FROM MEASUREMENTS
WHERE to_number(replace(VALUE,',','.'), '999999999D99999999999999999999999999999999999999','NLS_NUMERIC_CHARACTERS = ''.,''')
> to_number(replace(LOW,',','.'), '999999999D99999999999999999999999999999999999999','NLS_NUMERIC_CHARACTERS = ''.,''')
AND to_number(replace(VALUE,',','.'), '999999999D99999999999999999999999999999999999999','NLS_NUMERIC_CHARACTERS = ''.,''')
<=to_number(replace(HIGH,',','.'), '999999999D99999999999999999999999999999999999999','NLS_NUMERIC_CHARACTERS = ''.,''')
these query works for every number writing above, except exponential numbers like 9.9E+37.
I found a rewriting with TO_CHAR, but it doesnt work with varchar
Have anybody a solution to compare various numbers stored as varchar with each other?
thx
If you know they are all numbers, I would suggest using cast():
select cast(col as float)

I'm confused about Sqlite comparisons on a text column

I've got an Sqlite database where one of the columns is defined as "TEXT NOT NULL". Some of the values are strings and some can be cast to a DOUBLE and some can be case to INTEGER. Once I've narrowed it down to DOUBLE values, I want to do a query that gets a range of data. Suppose my column is named "Value". Can I do this?
SELECT * FROM Tbl WHERE ... AND Value >= 23 AND Value < 42
Is that going to do some kind of ASCII comparison or a numeric comparison? INTEGER or REAL? Does the BETWEEN operator work the same way?
And what happens if I do this?
SELECT MAX(Value) FROM Tbl WHERE ...
Will it do string or integer or floating-point comparisons?
It is all explained in the Datatypes In SQLite Version 3 article. For example, the answer to the first portion of questions is
An INTEGER or REAL value is less than any TEXT or BLOB value. When an INTEGER or REAL is compared to another INTEGER or REAL, a numerical comparison is performed.
This is why SELECT 9 < '1' and SELECT 9 < '11' both give 1 (true).
The expression "a BETWEEN b AND c" is treated as two separate binary comparisons "a >= b AND a <= c"
The most important point to know is that column type is merely an annotation; SQLite is dynamically typed so each value can have any type.
you cant convert text to integer or double so you wont be able to do what you want.
If the column were varchar you could have a chance by doing:
select *
from Tbl
WHERE ISNUMERIC(Value ) = 1 --condition to avoid a conversion from string to int for example
and cast(value as integer) > 1 --rest of your conditions

Determine MAX Decimal Scale Used on a Column

In MS SQL, I need a approach to determine the largest scale being used by the rows for a certain decimal column.
For example Col1 Decimal(19,8) has a scale of 8, but I need to know if all 8 are actually being used, or if only 5, 6, or 7 are being used.
Sample Data:
123.12345000
321.43210000
5255.12340000
5244.12345000
For the data above, I'd need the query to either return 5, or 123.12345000 or 5244.12345000.
I'm not concerned about performance, I'm sure a full table scan will be in order, I just need to run the query once.
Not pretty, but I think it should do the trick:
-- Find the first non-zero character in the reversed string...
-- And then subtract from the scale of the decimal + 1.
SELECT 9 - PATINDEX('%[1-9]%', REVERSE(Col1))
I like #Michael Fredrickson's answer better and am only posting this as an alternative for specific cases where the actual scale is unknown but is certain to be no more than 18:
SELECT LEN(CAST(CAST(REVERSE(Col1) AS float) AS bigint))
Please note that, although there are two explicit CAST calls here, the query actually performs two more implicit conversions:
As the argument of REVERSE, Col1 is converted to a string.
The bigint is cast as a string before being used as the argument of LEN.
SELECT
MAX(CHAR_LENGTH(
SUBSTRING(column_name::text FROM '\.(\d*?)0*$')
)) AS max_scale
FROM table_name;
*? is the non-greedy version of *, so \d*? catches all digits after the decimal point except trailing zeros.
The pattern contains a pair of parentheses, so the portion of the text that matched the first parenthesized subexpression (that is \d*?) is returned.
References:
https://www.postgresql.org/docs/9.6/static/sql-createcast.html
https://www.postgresql.org/docs/9.6/static/functions-matching.html
Note this will scan the entire table:
SELECT TOP 1 [Col1]
FROM [Table]
ORDER BY LEN(PARSENAME(CAST([Col1] AS VARCHAR(40)), 1)) DESC

String greater than or less than

I have the following data:
[sequences]
/a1
/a2
/a3
...
/a10
The query SELECT * FROM sequences WHERE nbr <= '/a10' should return the list above, instead it returns:
[results]
/a1
/a10
How do I make it return all the rows in the above list?
It works as it should. To compare the numeric value, you'll have to convert these to numbers somehow. A good start would be to use substr(yourfieldname, 3) to cut of the/a. Then you can useconvert` to typecast it to int, so your final query will look something like:
select * from sequences where convert(int, substr(nbr, 3)) <= 10
Mind that the exact functions and rules for converting strings to ints may very per dbms. This illustrates the general idea, though.
SELECT *
FROM sequences
WHERE toInt(substring (nbr, 2)) <= 10;
Name and syntax of 'substring'-function and 'toInt' will vary from db-implementation to db-implementation.