Sort text field - sql

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)

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;

Natural or Human Sort order

I have been working on this on for months. I just cannot get the natural (True alpha-numeric) results. I am shocked that I cannot get them as I have been able to in RPG since 1992 with EBCDIC.
I am looking for any solution in SQL, VBS or simple excel or access. Here is the data I have:
299-8,
3410L-87,
3410L-88,
420-A20,
420-A21,
420A-40,
4357-3,
AN3H10A,
K117GM-8,
K129-1,
K129-15,
K271B-200L,
K271B-38L,
K271D-200EL,
KD1051,
KD1062,
KD1092,
KD1108,
KD1108,
M8000-3,
MS24665-1,
SK271B-200L,
SAYA4008
The order I am looking for is the true alpha-numeric order as below:
AN3H10A,
KD1051,
KD1062,
KD1092,
KD1108,
KD1108,
K117GM-8,
K129-1,
K129-15,
MS24665-1,
M8000-3,
SAYA4008,
SK271B-200L
The inventory is 7800 records so I have had some problems with processing power as well.
Any help would be appreciated.
Jeff
In native Excel, you can add multiple sorting columns to return the ASCII code for each character, but if the character is a number, then add a large number to the code (e.g 1000).
Then sort on each of the helper columns, including the first column in the table, but not in the sort.
The formula:
=IFERROR(CODE(MID($A1,COLUMNS($A:A),1))+AND(CODE(MID($A1,COLUMNS($A:A),1))>=48,CODE(MID($A1,COLUMNS($A:A),1))<=57)*1000,"")
The Sort dialog:
The results:
You can implement a similar algorithm using VBA, and probably SQL also. I dunno about VBS or Access.
You could try using format for left padding the string in order by
select column
from my_table
order by Format(column, "0000000000")
Add a sorting column:
, iif (left(fieldname, 1) between '0' and '9', 1, 0) sortField
etc
order by sortField, FieldName
Lets say you have your data in column "A". If you put this formula in column "B" =IFERROR(IF(LEFT(A1,1)+1>0,"ZZZZZZZ "&A1,A1),A1), it will automatically add Z in front of all numerical values, so that they will naturally appear after all alphabetical values when you sort A-Z. later you can find&replace that funny ZZZZZZ string...
There a number of approaches, but likely the least amount of work is to build two columns that split out the delimiter (-) in this case.
You then “pad” the results (spaces, or 0) right justified, and then sort on the two columns.
So in the query builder we have this:
SELECT Field1,
Format(
Mid(field1,1,IIf(InStr(field1,"-")=0,50,InStr(field1,"-")-1)),
">##########") AS Expr1,
Format(
Mid(field1,IIf(InStr(field1,"-")=0,99,InStr(field1,"-")+1)),
">##########") AS Expr2
FROM Data
When we run the above raw query we get this:
So now in the query builder, simply sort on the first derived column, and then sort on the 2nd derived column.
Eg this:
Run the query, and we get this result:
Edit:
Looking at you desired results, it looks like above sort is wrong. We have to RIGHT just and pad with 0’s.
So this 2nd try:
SELECT Field1,
Left(Mid(field1,1,IIf(InStr(field1,"-")=0,30,InStr(field1,"-")-1))
& String(30,"0"),30) AS Expr1,
Left(Mid(field1,IIf(InStr(field1,"-")=0,99,InStr(field1,"-")+1))
& String(30,"0"),30) AS Expr2
FROM Data
The results are thus this:
Given your small table size, then the above query should perform quite well.

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

Sorting data in Access database where the column has numbers and letters

Please help me because I have been unable to get this right.
What is the access SQL to select this column(columnA) so that it returns a resultset with distinct values sorted first according to numbers and then to letters.
Here is the columns values: {10A,9C,12D,11G,9B,10C,9R,8T}
I have tried 'Select distinct ColumnA from tblClass order by 1'
but it returns {10A,10C,11G,12D,8T,9B,9C,9R} which is not what I want.
Thank you in advance.
You can use the Val() function for this. From the help topic: "The Val function stops reading the string at the first character it can't recognize as part of a number"
Val(10A) will give you 10, Val(9C) will give you 9, and so on. So in your query, order by Val(ColumnA) first, then ColumnA.
SELECT DISTINCT Val([ColumnA]) AS number_part, ColumnA
FROM tblClass
ORDER BY Val([ColumnA]), ColumnA;
SELECT DISTINCT ColumnA
FROM tblClass
ORDER BY CInt(LEFT(ColumnA,len(ColumnA)-1)), RIGHT(ColumnA,1);
If there last character is a letter and the others are a number.
Your data type is a string so it's sorting correctly, to get the result you want you're going to have to split your values into numeric and alphabetic parts and then sort first on the numeric then the alphabetic. Not being an Access programmer I can't help you with exactly how you're going to do that.
order by 1?
Don't you mean order by ColumnA?
SELECT DISTINCT ColumnA
FROM tblClass
ORDER BY ColumnA
I had a similar problem and used a dummie workaround:
changing a list of {10A,10C,11G,12D,8T,9B,9C,9R}
into {10A,10C,11G,12D,08T,09B,09C,09R} by adding the 0 before each <10 number.
now all items are the same length and access will sort correctly into {08T, 09B, 09C, 09R, 10A, 10C, 11G, 12D}
.
To achieve this, I copied this column into excel column A and used IF(LEN(A2)<3, concatenate("0", A2))

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;