Reputation: 3588
I have a MySQL table which has a column containing VARCHAR data. The data could be of the following type:
I need to pull the data from the table and sort the data matching this column, let's call it type
. The sorting should be as follows:
First everything starting with 'Q%' keeping in mind that the integer after Q also plays a role (Q5 should be before Q6) etc.
Following is everything starting with 'L%', same logic as above. The 'W%' follow next and last are just the simple integers.
So what's the query and especially the ORDER BY part that I need to write? I tried the following which gives no errors but does not order the items in the order that I want and I can't figure out what's the logic behind it:
SELECT * FROM table
ORDER BY
CASE type
WHEN type LIKE 'Q%' THEN 1
WHEN type LIKE 'L%' THEN 2
WHEN type LIKE 'W%' THEN 3
ELSE 4
END,
type ASC
I also tried with FIELD(...)
but I don't think it takes into account something like 'Q%' at all although it doesn't give an error either nor it sorts them properly.
Any tips or ideas?
Upvotes: 2
Views: 1071
Reputation: 272096
The second column should be sorted based on the integer value of the column:
SELECT `type`
FROM `table`
ORDER BY
CASE
WHEN `type` LIKE 'Q%' THEN 1
WHEN `type` LIKE 'L%' THEN 2
WHEN `type` LIKE 'W%' THEN 3
ELSE 4
END,
CASE
WHEN `type` LIKE 'Q%' THEN CONVERT(SUBSTRING(`type`, 2), SIGNED)
WHEN `type` LIKE 'L%' THEN CONVERT(SUBSTRING(`type`, 2), SIGNED)
WHEN `type` LIKE 'W%' THEN CONVERT(SUBSTRING(`type`, 2), SIGNED)
ELSE CONVERT(`type`, SIGNED)
END
Upvotes: 2
Reputation: 15941
This should allow desired ordering.
ORDER BY FIELD(LEFT(type,1), 'Q', 'L', 'W')
, CAST(type AS UNSIGNED)
, CAST(SUBSTRING(type, 2) AS UNSIGNED)
The first one ensures those letters happen in that order; anything beginning otherwise will be ordered earlier. This is a benefit since you want pure numbers first, but may cause issues if there are other prefixes not accounted for.
The second makes sure the numeric strings order themselves numerically (so you won't get things like 1, 11, 12, 100, 2
. For strings beginning with letters this usually results in 0 (no sort); though it would position unaccounted for prefixes (if they exist) BEFORE most pure numbers.
The third part performs nearly identically to the second ordering, but is effective for the prefixed strings' numeric portions.
Upvotes: 4
Reputation: 463
ok.. try this
This is if you do not want to see the manufactured order by field in the final answer..
select
list-all-fields-here again-except the ordering field we derived...
from
(SELECT
CASE type
WHEN type LIKE 'Q%' THEN 1
WHEN type LIKE 'L%' THEN 2
WHEN type LIKE 'W%' THEN 3
ELSE 4
END as MYORDERCOL,
**list-all-fields-here vs a * **
FROM table
) as tmp
order by tmp.MYORDERCOL ASC
I generally avoid using * and always like to list out the explicit fields for clarity
Upvotes: 1