Reputation: 3978
I have a hierarchical table with some data in it. I've handled sorting them in a hierarchical way but there is a bug in it. I use a field named Path
to do this. let's look at the table first:
The problem here is that mysql compares each pair of Paths as text. That if you look at those last two rows, 15 is bigger than 6 and should be swapped with the row under it.
My question is how can I compare each part of the path as numbers separated by dots?
Upvotes: 2
Views: 416
Reputation: 1819
Let's say you have sample data like this :
id num_text
---------------
1 0.4.3
2 0.4.2
3 0.4.15
4 0.4.23
This is query you need :
select *
from table
order by concat(
substr(num_text,1,1),
substr(num_text,3,1),
lpad(substr(num_text,5,2),2,'0')
) asc
sample output :
id num_text
---------------
2 0.4.2
1 0.4.3
3 0.4.15
4 0.4.23
Explanation :
First, you need to make each values have the same length. For example, we convert 0.4.2 to 0402, 0.4.3 to 0403
, etc. So this query :
select id,
concat(
substr(num_text,1,1),
substr(num_text,3,1),
lpad(substr(num_text,5,2),2,'0')
) as x
from table
the output should be :
id x
--------------
1 0403
2 0402
3 0415
4 0423
The sample above is for the simple pattern. If you have more complicated or bigger pattern like 1.23.23.123
or 12.1.34.234
, You need more mysql string function like LPAD
, SUBSTR
, etc.
Upvotes: 3
Reputation: 1594
What you can do is use two digits for each step of your path i.e. instead of 0.4.6
save 0.04.06
which is smaller than 0.04.15
What I'd do on top of that is convert the path to numbers using following formula
0.1.7.9.10.13 -> 0.1791013
multiply with 10000000
0.1791013 * 10000000 = 1791013
Upvotes: 0
Reputation: 33945
Here's a little hack:
SELECT INET_ATON('0.4.15')a,INET_ATON('0.4.6')b;
+--------+--------+
| a | b |
+--------+--------+
| 262159 | 262150 |
+--------+--------+
Upvotes: 0