SQLite3 Order by highest/lowest numerical value - sql

I am trying to do a query in SQLite3 to order a column by numerical value. Instead of getting the rows ordered by the numerical value of the column, the rows are ordered alphabetically by the first digit's numerical value.
For example in the query below 110 appears before 2 because the first digit (1) is less than two. However the entire number 110 is greater than 2 and I need that to appear after 2.
sqlite> SELECT digit,text FROM test ORDER BY digit;
1|one
110|One Hundred Ten
2|TWO
3|Three
sqlite>
Is there a way to make 110 appear after 2?

It seems like digit is a stored as a string, not as a number. You need to convert it to a number to get the proper ordering. A simple approach uses:
SELECT digit, text
FROM test
ORDER BY digit + 0

Related

Extract the highest key:value pair from a string in Standard SQL

I have the following data type below, it is a type of key value pair such as 116=0.2875. Big Query has stored this as a string. What I am required to do is to extract the key i.e 116 from each row.
To make things more complicated if a row has more than one key value pair the iteration to be extracted is the one with the highest number on the right e.g {1=0.1,2=0.8} so the extracted number would be 2.
I am struggling to use SQL to perform this, Particularly as some rows have one value and some have multiple:
This is as close as I have managed to get where I can create a bit of code to extract the highest right hand value (which I don't need) but I just cant seem to create something to either get the whole key/value pair which would be fine and work for me or just the key which would be great.
column
,(SELECT MAX(CAST(Values AS NUMERIC)) FROM UNNEST(JSON_EXTRACT_ARRAY(REPLACE(REPLACE(REPLACE(column,"{","["),"}","]"),"=",","))) AS Values WHERE Values LIKE "%.%") AS Highest
from `table`
Here is some sample data:
1 {99=0.25}
2 {99=0.25}
3 {99=0.25}
4 {116=0.2875, 119=0.6, 87=0.5142857142857143}
5 {105=0.308724832214765}
6 {105=0.308724832214765}
7 {139=0.5712754555198284}
8 {127=0.5767967894928858}
9 {134=0.2530120481927711, 129=0.29696599825632086, 73=0.2662459427947186}
10 {80=0.21242613001118038}
Any help on this conundrum would be greatly appreciated!
Consider below approach
select column,
( select cast(split(kv, '=')[offset(0)] as int64)
from unnest(regexp_extract_all(column, r'(\d+=\d+.\d+)')) kv
order by cast(split(kv, '=')[offset(1)] as float64) desc
limit 1
) key
from your_table
if applied to sample data in your question - output is

How to calculate the ratio of this column with 2 rows

I am very new to SQL and am having difficulty figuring out hot to divide row1 (101) by row2 (576).
COUNT
101
576
I want the output to be a single value expressed to 2 decimal places.
Any tips?
Thanks for the help
For two rows, it's easy.
If you have a big input table, and you want to divide the first row by the second, the third row by the fourth, etc, then you need an ordering column to save yourself.
So, with a two-row table (remember, tables are never ordered), you just rely on the fact that you divide the smaller number by the bigger number.
Here goes:
WITH
-- your input ...
input(counter) AS ( -- count is reserved word, use another name ...
SELECT 101
UNION ALL SELECT 576
)
-- cheat and just divide the smaller by the bigger
-- as "#Gordon Linoff" suggests
-- force a float division by adding a non-integer operand
-- and hard-cast it to DECIMAL(5,2)
SELECT
CAST(
MIN(counter) * 1.00 / MAX(counter)
AS DECIMAL(5,2)
) AS result
FROM input;
-- out result
-- out ----------
-- out 0.18
If, however, you have many rows, and you always need to divide the first row by the second, the third row by the fourth, that is, each odd row in the order by the next even row in the order, then you need an ordering column.
Is your problem just what you suggested, or is there more to it?
There is no such thing as row "1" or "2" in a table. Tables represent unordered sets, so without a column specifying the ordering, there is no first or second row.
You can use aggregation to divide by min by the max:
select min(count) * 1.0 / max(count)
from t;
Note the * 1.0. Postgres does integer division, so you want to convert to something with a decimal point.

T - SQL statement for number ranges

Create table temp
(
ID nvarchar(50)
)
ID contains numeric values prevailing zeros in some cases so it is defined as varchar
How to get values starts with 3555 to 3999 and 8000 to 9999.There is no specific rule that length is always 4.
Eg:
3555
35688888888888
3590909
8000
85805667
all of the values are valid and are to be fetched.
Please let me know T- SQL statement for the above scenario
You can use few expressions with LIKE. If you have an index on ID, it would use it, so it will be efficient. Something like this:
SELECT
ID
FROM
temp
WHERE
ID LIKE '3[5-9]%'
OR ID LIKE '[89]%'
LIKE '3[5-9]%' matches any string that starts with 3 and which second character is 5 or 6 or 7 or 8 or 9. After these two characters there can be 0 or more other characters. Any number of extra characters.
LIKE '[89]%' matches any string that starts with 8 or 9 and any number characters after.
You can extract the first four chars, convert that to a number and query like this:
SELECT
[ID]
FROM temp
WHERE convert(int,LEFT([ID],4)) BETWEEN 3500 AND 3999
OR convert(int,LEFT([ID],4)) BETWEEN 8000 AND 9999
For lots of data this will be horribly slow, so if you need performance I would recommend to add an indexed int column to the table where you store the number that represents the first four digits of ID.

Select statement with offset in like

I have an entry "123456789" in my table.
Select * from map where col like '%1%5%6%7%9'.
I want to retrieve the records where the order of the input sequence matches, but i also want to ensure that the distance between any 2 matching digits is less than 2.
Is there any way i can specify an offset ?
The input is 189, and it selects the record, but i want 1.8.9 to be within 2 of each other. 12879 would be an acceptable output but 123456789 would not be.
Below statement requires 3 to 5 characters between 1 and 5:
SELECT * FROM map WHERE col LIKE '%1___%5%6%7%9' AND col NOT LIKE '%1______%5%6%7%9%'
Using _s you may force any count of characters.
EDIT: Character corrected. Source: SQLite expression
Check in this SQL Fiddle sample.

How do I get the last three digits of a varying length column?

I want to write a select statement and get the last three digits of all of the rows in a column for which the length varies.
Any ideas on how I can achieve this?
Hypothetical column:
12312398098098
127865275
I want the resulting column to have the values:
Resulting column after the script:
098
275
SELECT RIGHT(CONVERT(VARCHAR(4000), [hypothetical column]), 3) FROM table;
(Added a convert in case this is a numeric column.)