Sort by Alphabets, Numbers, Special character order - sql

SELECT * FROM details
ORDER BY cast(SUBSTRING(name,'^[a-zA-Z]+') as varchar) orderDirection NULLS LAST,
cast(SUBSTRING(name,'^\d+') as numeric) orderDirection NULLS LAST, name orderDirection;
This query retrieves data in ASC or DESC depends on the input we gave for 'orderDirection',
But the problem is Capital letters and small letters also will be treated as separate sort.
So help me in finding proper query with adding something in this query itself(Because I am using some generic codes for creating this)
Current Result:
"Came"
"Result"
"Result came"
"came"
"result"
"01 Result"
"# Result"
Expected Result:
"Came"
"came"
"Result"
"result"
"Result came"
"01 Result"
"# Result"

Get a recent PostgreSQL version that is built with a recent ICU library and create your own collation:
CREATE COLLATION english_weird (
PROVIDER = 'icu',
LOCALE = 'en-u-kr-punct-symbol-currency-digit-latn'
);
Then use it for sorting:
ORDER BY name COLLATE english_weird DESC
If you always want that order for that column, define it accordingly:
ALTER TABLE details
ALTER name TYPE text COLLATE english_weird;

If you convert the strings to lowercase before ordering you will get the results you want:
SELECT * FROM details
ORDER BY cast(SUBSTRING(LOWER(name,'^[a-z]+')) as varchar) DESC NULLS LAST,
cast(SUBSTRING(name,'^\d+') as numeric) DESC NULLS LAST,
LOWER(name) DESC;

Related

Need to find string using bigquery

We have below string column and having below data
and I want to find Null count present in string columns means how many times null value('') present in front of id column present in select statement
using big query.
Don't use string position.
Expected output:
count of null ('')id =3
1st row,2nd row and 5th row
Below is for BigQuery Standard SQL
#standardSQL
SELECT
FORMAT(
"count of null ('')id = %d. List of id is: %s",
COUNT(*),
STRING_AGG(CAST(ID AS STRING))
) AS output
FROM `project.dataset.table`
WHERE REGEXP_CONTAINS(String, r"(?i)''\s+(?:as|)\s+(?:id|\[id\])")
if to apply to sample data from your question - the output is
Row output
1 count of null ('')id = 3. List of id is: 1,2,5
The idea is to unify all strings to something you can query with like = "%''asid%" or regex
First replace all spaces with ''
replace "[", "]" with ''.
Make the use of " or ' consistent.
Then query with like.
For example:
select 1 from (select replace(replace(replace(replace('select "" as do, "" as [id] form table1',' ',''),'[',''),']',''),'"',"'") as tt)
where tt like ("%''asid%")
Its not a "smart" idea but its simple.
A better idea will be to save the query columns in a repeat column '"" as id' and the table in another column.
You don't need to save 'select' and 'from' this way you can query easily and also assemble a query from the data.
If I understand correctly, you want to count the number of appearances of '' in the string column.
If so, you can use regexp_extract_all():
select t.*,
(select count(*)
from unnest(regexp_extract_all(t.string, "''")) u
) as empty_string_count
from t;

How to order by a text column that contains int in SQL?

My current SQl statement is:
SELECT distinct [Position] FROM [Drive List] ORDER BY [Position]ASC
And the output is ordered as seen below:
1_A_0_0_0_0_0
1_A_0_0_0_0_1
1_A_0_0_0_0_10
1_A_0_0_0_0_11
1_A_0_0_0_0_12
1_A_0_0_0_0_13 - 1_A_0_0_0_0_24, and then 0_2-0_9
The field type is Text in a Microsoft Access Database. Why is the order jumbled and is there any way of correctly sorting the values?
"Why the order is jumbled":
The order is only jumbled because you are compiling it with your human brain and are applying more value than the computer does because of your symbolic understand of what the values represent. Parse the output as though you could only understand it as an array of character strings, and you were trying to determine which string is the greatest, all the while knowing nothing about the symbolic value of each character. You will find that the output your query generated is perfectly logical and not at all jumbled.
"Any way of correctly sorting the values"
This is a design issue and it should be addressed if it really is a problem.
Change 1_A_0_0_0_0_0 to 1_A_0_0_0_0_00
Change 1_A_0_0_0_0_1 to 1_A_0_0_0_0_01
Change 1_A_0_0_0_0_2 to 1_A_0_0_0_0_02
etc
This will make the problem go away.
Use these two separate queries:
SELECT distinct [Position] FROM [Drive List] WHERE [Position] LIKE '1_A_0_0_0_0_?' ORDER BY [Position] ASC
SELECT distinct [Position] FROM [Drive List] WHERE [Position] LIKE '1_A_0_0_0_0_??' ORDER BY [Position] ASC
...add to a temp table and append to get the results to display properly.
If you want sorting which incorporates the numerical values of those substrings, you can cast them to numbers.
In the simplest case, you're concerned with only the digit(s) after the 12th character. That case would be fairly easy.
SELECT
sub.Position,
Left(sub.Position, 12) AS sort_1,
Val(Mid(sub.Position, 13)) AS sort_2
FROM
(
SELECT DISTINCT [Position] FROM [Drive List]
) AS sub
ORDER BY 2, 3;
Or if you want to display only the Position field, you could do it this way ...
SELECT
sub.Position
FROM
(
SELECT DISTINCT [Position] FROM [Drive List]
) AS sub
ORDER BY
Left(sub.Position, 12),
Val(Mid(sub.Position, 13));
However, your actual situation could be much more challenging ... perhaps the initial substring (everything up to and including the final _ character) is not consistently 12 characters long, and/or includes digits which you also want sorted numerically. You could then use a mix of InStr(), Mid(),and Val() expressions to parse out the values to sort. But that task could get scary bad real fast! It could be less effort to alter the stored values so they sort correctly in character order as #Justin suggested.
Your jumbled order is caused because it is a text field. As for solutions you could attempt to add an additional column in your table that is numeric and order by that instead of Position. I would need more information about what data you have and what it means to suggest a good way to do this.
This is the right sort for a string.
In alphabetical order 10 come before 2.
For orderby the last number you can try with SUBSTRING and CAST (or CONVERT) commands

Sort text field

I have the following records and need to sort them accordingly:
AB*1
AB*2
AB*10
AB*100
I am using the following SQL Statement which works perfectly, BUT only for records which are filtered to a specific criteria.
SELECT Column1
FROM dbo.Table1
ORDER BY LEN(Column1), Column1
WHERE Column1 Like 'AB*'
When I remove the Where clause in the example, the record AB*100 appears way down below. Obiously, it has grouped together all the records with the Length of 4 then it starts all over with the records with length of 5 and so on.
Is it possible to order these so all before the asterisk are grouped together and sorted correctly?
The first character "alphabetically" is actually "no character". So it's not so much that "a string of 4 comes first". For example, the following are in order...
AB*1
AB*2
AB*10
AB*100
CD*1
CD*2
CD*10
CD*100
You could order by the first 3 characters as a string, and the trailing characters as a number. Provided that's how your data behaves...
ORDER BY
LEFT(column1, 3),
CLNG(MID(column1, 4, 8000))
Or you could pad out your values and order them as if they looked like this...
AB*100
AB*10Z
AB*1ZZ
AB*2ZZ
Using this kind of ORDER BY statement...
ORDER BY
column1 & string(8000 - LEN(column1), "z")
But these are all work-arounds to force an 'un-natural' ordering, as at present you're getting the 'correct' ordering.
This is likely to be slow:
ORDER BY Mid(Column1,1,Instr(Column1,"*"))
Edit re comment
SELECT Column1
FROM Table
ORDER BY Mid([Column1],1,InStr([Column1],"*")),
Val(Mid([Column1],InStr([Column1],"*")+1));
Sample data used in test:
ID
ab*1
ab*10
ab*2
abcdef*a1
abcdef*10
abcdef*40a
For nulls, just add a few zero-length strings.
SELECT column1
FROM Table
ORDER BY Mid([column1] & "",1,InStr([column1] & "","*")),
Val(Mid([column1] & "",InStr([column1] & "","*")+1));
it seems this will do what you want, unless I misunderstand
SELECT Column1
FROM dbo.Table1
ORDER BY left(Column1,2), LEN(Column1)

How do I sort a VARCHAR column in PostgreSQL that contains words and numbers?

I need to order a select query using a varchar column, using numerical and text order. The query will be done in a java program, using jdbc over postgresql.
If I use ORDER BY in the select clause I obtain:
1
11
2
abc
However, I need to obtain:
1
2
11
abc
The problem is that the column can also contain text.
This question is similar (but targeted for SQL Server):
How do I sort a VARCHAR column in SQL server that contains words and numbers?
However, the solution proposed did not work with PostgreSQL.
Thanks in advance, regards,
I had the same problem and the following code solves it:
SELECT ...
FROM table
order by
CASE WHEN column < 'A'
THEN lpad(column, size, '0')
ELSE column
END;
The size var is the length of the varchar column, e.g 255 for varying(255).
You can use regular expression to do this kind of thing:
select THECOL from ...
order by
case
when substring(THECOL from '^\d+$') is null then 9999
else cast(THECOL as integer)
end,
THECOL
First you use regular expression to detect whether the content of the column is a number or not. In this case I use '^\d+$' but you can modify it to suit the situation.
If the regexp doesn't match, return a big number so this row will fall to the bottom of the order.
If the regexp matches, convert the string to number and then sort on that.
After this, sort regularly with the column.
I'm not aware of any database having a "natural sort", like some know to exist in PHP. All I've found is various functions:
Natural order sort in Postgres
Comment in the PostgreSQL ORDER BY documentation

sql order by numeric string

I am using oracle 10. I need to sort my result set according to two numeric string fields.
one sort criterion field holds data like this:
FIELD1:
FO-100001001001
FO-100001002001
FO-100001003001
SQ-200001003001
FC-102001003001
the other :
FIELD2:
000203
000567
349990
I need to combine the two criterion , the first criterion take the priority , the result needs an ascending order.
How do I write this sql ?
Since the numbers are zero-padded, you can simply compare them as strings:
SELECT ...
FROM ...
ORDER BY field1 ASC, field2 ASC
Or if you want to ignore the prefix in field1:
SELECT ..., SUBSTR(field1, 3) AS stripped_field1
FROM ...
ORDER BY stripped_field1 ASC, field2 ASC
I am assuming that by "numeric string", you mean "varchar", and that alpha-numeric sorting works for you (which it should if the format is fixed and you have the leading zeroes).
select * from table order by field1, field2;