on 2019 Dec 24 10:12 AM
Apparently StrCmpLogicalW is used by modern File Explorer implementations to sort file names like this
a 1 a 1.txt a 2 a 2.txt a 2 a 11.txt a 11 a 11.txt a 22 a 22.txt a 22 a 111.txt
rather than use the traditional dir /ON and ORDER BY sorting
a 1 a 1.txt a 11 a 11.txt a 2 a 11.txt a 2 a 2.txt a 22 a 111.txt a 22 a 22.txt
Sooooo, I would like the freedom to choose the StrCmpLogicalW method for ORDER BY (and dir, if possible).
Any thoughts?
[ insert being lazy meme here :]
This should do the trick. Maybe you have to add something for the '.' in the string. Use the function in the order by and pass the column needed to sort on as in_strValue and the maximum value of the length of the string in the in_MaxFieldLength parameter.
create or replace function usr.OrderStringByNumeric(in in_strValue long varchar,in in_MaxFieldLength integer) returns long varchar begin declare l_EndNumeric integer; declare l_EndText integer; declare l_StartNumeric integer; declare l_StartText integer; declare l_strResult long varchar; // set l_strResult = ''; // currentloop: loop if in_strValue = '' then leave currentloop end if; // set l_StartText = patindex('%[A-Z]%',in_strValue); // if l_StartText = 1 then set l_EndText = patindex('%[A-Z][0-9-]%',in_strValue); if l_EndText = 0 then set l_StrResult = l_strResult || repeat('>',in_MaxFieldLength -l_EndTextlength(in_strValue) + 1) || substring(in_strValue,l_StartText); leave currentloop; else set l_StrResult = l_strResult || repeat('>',in_MaxFieldLength - l_EndText + 1) || substring(in_strValue,l_StartText,l_EndText); set in_strValue = substring(in_strValue,l_EndText+1); end if; end if; // set l_StartNumeric = patindex('%[0-9]%',in_strValue); if l_StartNumeric = 1 then set l_EndNumeric = patindex('%[0-9][A-Z-]%',in_strValue); if l_EndNumeric = 0 then set l_StrResult = l_strResult || repeat('*',in_MaxFieldLength -l_EndNumericlength(in_strValue) + 1) || substring(in_strValue,l_StartNumeric); leave currentloop; else set l_StrResult = l_strResult || repeat('*',in_MaxFieldLength - l_EndNumeric + 1) || substring(in_strValue,l_StartNumeric,l_EndNumeric); set in_strValue = substring(in_strValue,l_EndNumeric+1); end if; end if; end loop; // return l_strResult end; grant execute on usr.OrderStringByNumeric to usr;
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Alas...
CREATE TABLE t ( s VARCHAR ( 20 ) ); INSERT t VALUES ( 'a11a11' ); INSERT t VALUES ( 'a1a1' ); INSERT t VALUES ( 'a2a11' ); INSERT t VALUES ( 'a2a2' ); INSERT t VALUES ( 'a22a22' ); INSERT t VALUES ( 'a22a111' ); COMMIT; SELECT * FROM t ORDER BY OrderStringByNumeric ( s, 20 ); s 'a1a1' 'a2a11' out of order 'a2a2' 'a11a11' 'a22a111' out of order 'a22a22'
User | Count |
---|---|
81 | |
11 | |
10 | |
10 | |
10 | |
8 | |
7 | |
7 | |
5 | |
5 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.