Reputation: 380
Long-time reader, first-time poster here.
I'm trying to figure out how to sort a list of artists for a music app I'm writing.
To help understand the database structure: Rather than having a relational system where each song in the songs table has an artist ID that references a row in the artists table, I simply have a list of songs with the artist's name as a string in a column. I then use GROUP BY artist
in a MySQL query to return a list of individual artists.
My app retrieves this data from my server in the form of a JSON-encoded array which is the result of the following MySQL query:
SELECT artist FROM songs GROUP BY artist ORDER BY artist ASC
However, this query results with artists with names like &i, +NURSE, and 2007excalibur2007 being sorted before the alphabetical results (such as AcousticBrony, ClaireAnneCarr, d.notive, etc.).
What I need is the artists whose names begin with numbers and symbols returned after the alphabetically-sorted artist list.
The solution can be PHP-based, but I'd prefer the elegance of it being done in the MySQL query.
Upvotes: 6
Views: 11281
Reputation: 1522
if you want sort by symbol first
then use below query
ORDER BY artist REGEXP '^[^A-Za-z0-9]' DESC, artist ASC
Upvotes: 0
Reputation: 26753
ORDER BY ASCII(SUBSTR(artist, 1, 1)) NOT BETWEEN 65 AND 122, artist
This will order all artists that start with an alphabetical character before non alphabetical.
Note that because of how ascii works [ \ ] & _ ` will be considered alphabetical. If this matters you can split it into two boolean expressions to do the upper and lower case letters separately.
Or maybe:
ORDER BY ASCII(UPPER(SUBSTR(artist, 1, 1))) NOT BETWEEN 65 AND 90, artist
Be aware that this will only work for ascii characters. Letters that are part of other character sets won't be recognized as such.
Upvotes: 0
Reputation: 108686
You can add an extra ORDER BY
clause that puts the items that start with a non-alphabetic character last, like so:
SELECT artist
FROM songs
ORDER BY artist REGEXP '^[^A-Za-z]' ASC, artist
This should move every artist that doesn't start with A-Z or a-z to the end of your ordering.
Upvotes: 3
Reputation: 838326
This will put all the artists who's names begin with a letter in a-z before those that don't:
SELECT DISTINCT artist
FROM songs
ORDER BY artist REGEXP '^[a-z]' DESC, artist
See it working online: sqlfiddle
But you might prefer to store a second column with the simplified name so that you can put them in an order that makes more sense:
artists
artist | simplified_name
------------------------------------
&i | i
+NURSE | nurse
2007excalibur2007 | excalibur
The values for simplified_name
cannot be easily generated in MySQL, so you may want to use a general purpose programming language to pull out all the artists, transform them to simplified names, then populate the database with the results.
Once this is done, you can use this query:
SELECT DISTINCT artist
FROM artists
ORDER BY simplified_name
Upvotes: 13