MySql sort varchar containing text + numeric data - mysql

I'd like to order by a varchar field that contains text and numeric data.
The values in the database / and also the order outputted with
"ORDER BY CAST(product AS SIGNED)"
Doppel 80x200cm
Classic 100x200cm
Mega 240x250
Classic 85x200cm
Profi 60x235cm
The ORDER I'd like to have is an order first by the text than by number:
(Please keep in mind that the productnames could be one of the following: Text only, Text+Number, Text+Number+Text)
Classic 85x200cm
Classic 100x200cm
Doppel 80x200cm
Mega 240x250
Profi 60x235cm
I also tried the following without a correct result:
"ORDER BY CAST(SUBSTRING(product,LOCATE(' ',product)+1) AS SIGNED) ASC"
"ORDER BY CASE WHEN product REGEXP '^[0-9]+$' THEN product*1 else 999999 END"
Any help would be appreciated!

This solution comes quite close. Off course you have to put the names in an php array first.
http://php.net/manual/de/function.natcasesort.php

Related

MySql sorting float data type

Hi guys im having a problem sorting a column named "change" which is a reserved word that has a data type of "FLOAT" in the database.
tried different ways but still cant get it.
"select * from data order by CAST('change' AS SIGNED) DESC";
"select * from data order by ABS(change) DESC";
"select * from data order by ABS(change - float) DESC";
"select CAST(change as float) AS ABC* from data order by ABC DESC";
i tried lots of different combinations but still no luckenter image description here
heres a picture of my sample database
thank you in advance!
Use back ticks
ORDER BY `CHANGE` DESC
Each RDBMS has different way of handling reserved words. MySQL uses back ticks : `
The error you got has nothing to do with casting .
As user 'sagi' suggested, using the reserved word "change", theres no need for casting or single quotes but instead back ticks work on the original question. for mac its on the left side of number 1 on the keyword. Thank you all!

Text manipulation of strings containing "The "

I have a table in a MySQL database which contains data like this;
ID text
1 Action Jackson
2 The impaler
3 The chubby conquistador
4 Cornholer
I want to display them in alphabetical order minus the leading "The ". This is what I've come up with which works.
SELECT ID, CASE LEFT(l.text, 4) WHEN "The " THEN CONCAT(RIGHT(l.text, LENGTH(l.text) - 4), ", The") ELSE l.text END AS "word"
FROM list l
This solution seems a little clunky, does anyone have a more elegant answer?
I think this is what you are looking for:
SELECT ID,
text
FROM list l
ORDER BY TRIM(LEADING 'The ' FROM text);
If you can at all, I would think of restructuring your data a bit.. Its hundreds of times better to rely on mysql indexes and proper sorting instead of doing it dynamically like this.
How about adding a field that drops the 'The ', and sort on that? You could make sure that this secondary field is always correct with a few triggers.
SELECT TRIM(LEADING 'The' FROM text) as word
FROM list
ORDER BY TRIM(LEADING 'The' FROM text)

MySQL search within the last 5 characters in a column?

My user table has a column "name" which contains information like this:
Joe Lee
Angela White
I want to search for either first name or last name efficiently. First name is easy, I can do
SELECT * FROM user WHERE name LIKE "ABC%"
But for last name, if I do
SELECT * FROM user WHERE name LIKE "%ABC"
That would be extremely slow.
So I am thinking about counting the characters of the input, for example, "ABC" has 3 characters, and if I can search only the last three characters in name column, that would be great. So I want something like
SELECT * FROM user WHERE substring(name, end-3, end) LIKE "ABC%"
Is there anything in MySQL that can do this?
Thanks so much!
PS. I cannot do fulltext because our search engine doesn't support that.
The reason that
WHERE name LIKE '%ith'
is a slow way to look for 'John Smith' by last name is the same reason that
WHERE Right(name, InStr(name, ' ' )) LIKE 'smi%'
or any other expression on the column is slow. It defeats the use of the index for quick lookup and leaves the MySQL server doing a full table scan or full index scan.
If you were using Oracle (that is, if you worked for a formerly wealthy employer) you could use function indexes. As it is you have to add some extra columns or some other helping data to accelerate your search.
Your smartest move is to split your first and last names into separate columns. Several other people have pointed out good reasons for doing that.
If you can't do that you could try creating an extra column which contains the name string reversed, and create an index on that column. That column will have, for example, 'John Smith' stored as 'htimS nhoJ'. Then you can search as follows.
WHERE nameReversed LIKE CONCAT(REVERSE('ith'),'%')
This search will use the index and be decently fast. I've had good success with it.
You're close. In MySQL you should be able to use InStr(str, substr) and Right(str, index) to do the following:
SELECT * FROM user WHERE Right(name, InStr(name, " ")) LIKE "ABC%"
InStr(name, " ") returns the index of the Space character (you may have to play with the " " syntax). This index is then used in the Right() function to search for only the last name (basically; problems arise when you have multiple names, multiple spaces etc). LIKE "ABC%" would then search for a last name starting with ABC.
You cannot use a fixed index as names that are more than 3 or less than 3 characters long would not return properly as you suggest.
However, as Zane said, it's a much better practise to use seperate fields.
If it is a MyIsam table, you may use Free text search to do the same.
You can use the REGEXP operator:
SELECT * FROM user WHERE name REGEXP "ABC$"
http://dev.mysql.com/doc/refman/5.1/en/regexp.html

MySQL Sort Alphabetically but Ignore "The"

I have MySQL database that has a table with book data in it. One of the columns in the table is called "title". Some of the titles begin the word "the" and some do not.
Example:
"The Book Title One"
"Book Title Two"
"Book Title Three"
I need to pull these out of the database in alphabetical order, but I need to ignore the "the" in the beginning of the titles that start with it.
Does SQL (specifically MySQL) provide a way to do this in the query?
do a case when to check if the column value starts with the and if it does, return the title without the 'The'. This will be a new column that you will be using later on for the sort order
select title, case when title like 'The %' then trim(substr(title from 4)) else title end as title2 from tablename order by title2;
You can use a CASE statement in the ORDER BY and the use REGEXP or LIKE to match strings that start with words you would like to remove.
In the example below I find all words that begin with a, an, or the followed by a space, and then remove everything up to the space, and trim away additional white space (you might have two or spaces following an instance of the).
SELECT *
FROM books
ORDER BY
CASE
WHEN title REGEXP '^(A|An|The)[[:space:]]' = 1 THEN
TRIM(SUBSTR(title , INSTR(title ,' ')))
ELSE title
END ;
if you are sure that you will NEVER EVER have a typo (and use lowercase instead of uppercase)
select *
from books b
order by UPPER(LTRIM(Replace(b.Title, 'The', '')))
Otherwise your sorting will do all Upper and then all lower.
for example, this is ascending order:
Have a Great Day
Wild west
Zorro
aZtec fries are hotter
alfred goes shopping
bart is small
will i am not
adapted from AJP's answer
I've seen some convoluted answers here which I tried but were just wrong (didn't work) or unsafe (replaced every occurrence of 'the'). The solution I believe to be easy, or maybe I'm getting it wrong or not considering edge cases (sincerely, no sarcasm intended).
... ORDER BY SUBSTRING(UPPER(fieldname), IF(fieldname LIKE 'The %', 5, 1))
As stated elsewhere, UPPER just prevents ASCII sorting which orders B before a (note the case difference).
There's no need for a switch-case statement when there is only one condition, IF() will do
I'm using MySQL 5.6 and it seems like the string functions are 1-indexed, in contrast to say PHP where strings are 0-indexed (this caught me out). I've tested the above on my dataset and it works
select *
from books b
order by LTRIM(Replace(b.Title, 'The', ''))
PLease note this will replace The from the title.. no matter where in the title. so use substring to get first 3 characters.
Simply:
SELECT Title
FROM book
ORDER BY IF(Title LIKE "The %", substr(Title, 5), Title);
Explanation:
We use the IF function to strip the "The" (if present) from the beginning of the string before returning the string to the ORDER BY clause. For more complex alphabetization rules we could create a user-defined function and place that in the ORDER BY clause instead. Then you would have ...ORDER BY MyFunction(Title).

MySQL sort by name

Is ir possible to sort a column alphabetically but ignoring certain words like e.g 'The'
e.g.
A normal query would return
string 1
string 3
string 4
the string 2
I would like to return
string 1
the string 2
string 3
string 4
Is this possible?
EDIT
Please note I am looking to replace multiple words like The, A, etc... Can this be done?
You can try
SELECT id, text FROM table ORDER BY TRIM(REPLACE(LOWER(text), 'the ', ''))
but note that it will be very slow for large datasets as it has to recompute the new string for every row.
IMO you're better off with a separate column with an index on it.
For multiple stopwords just keep nesting REPLACE calls. :)
This will replace all leading "The " as an example
SELECT *
FROM YourTable
ORDER BY REPLACE(Val,'The ', '')
Yes, it should be possible to use expressions with the ORDER-part:
SELECT * FROM yourTable ORDER BY REPLACE(yourField, "the ", "")
I have a music listing that is well over 75,000 records and I had encountered a similar situation. I wrote a PHP script that checked for all string that began with 'A ', 'An ' or 'The ' and truncated that part off the string. I also converted all uppercase letters to lowercase and stored that string in a new column. After setting an index on that column, I was done.
Obviously you display the initial column but sort by the newly-created indexed column. I get results in a second or so now.