MySQL sort by name - mysql

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.

Related

MySQL : replace occurence of a string in field except first one

I want to update all fields of a column, a lot of them have a desired string in there, but I want this string to be in only each field once, for instance :
"MyString OtherString MyString AnotherString AndAnother MyString"
to
"MyString OtherString AnotherString AndAnother"
would you have any idea on how to achieve this ?
If "MyString" will always occur as the first term in the field, this would work:
update MyTable set MyField = replace(MyField, ' MyString','')
The key point above is that we look for occurrences of "MyString" with a leading space, so the first occurrence at the beginning of the field will be ignored.
However, my guess is this might be too fragile - what if the first occurrence of "MyString" is not at the beginning of the field?
in this latter case you need the following:
UPDATE
MyTable
SET
MyField =
CONCAT(
LEFT(MyField,INSTR(MyField,'MyString') + LENGTH('MyString')),
REPLACE(RIGHT(MyField, LENGTH(MyField) - (INSTR(MyField,'MyString') + LENGTH('MyString'))), 'MyString','')
)
What this does is to split the field into two, the first part up to and including the first occurrence of "MyString", and the second part replacing all further occurrences of it.

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)

How do I convert a string of words into multiple rows of a Table using MySql command Line

I have a string such as,
"This is a sting and I dont know how long I am"
I want to turn every word in string into a row for my sql table so that I get:
ThisIs a string and I dont know etc...
I need to be able to do this with the MySql command line. (I also need an adjacent column to all be filled with ones on every row, incase that helps/changes your answer) I was thinking I could somehow use INSERT String (Words, num) Values (#words, 1) but I dont know how to get it to add every word. Is there any easy way to do this? If not, how would it be done?
MySQL does not have a function to split a delimited string. This problem is heavily discussed on MySQL manual page (search "split"), although there is no direct solution to handle variable number of elements.
Instead of that, I would help myself to generate such a query:
SELECT CONCAT('INSERT INTO t1 VALUES ("', REPLACE(REPLACE(TRIM(string_column), '"', '\\"'), ' ', '", "'), '")') FROM t2_with_string

Finding number of occurence of a specific string in MYSQL

Consider the string "55,33,255,66,55"
I am finding ways to count number of occurence of a specific characters ("55" in this case) in this string using mysql select query.
Currently i am using the below logic to count
select CAST((LENGTH("55,33,255,66,55") - LENGTH(REPLACE("55,33,255,66,55", "55", ""))) / LENGTH("55") AS UNSIGNED)
But the issue with this one is, it counts all occurence of 55 and the result is = 3,
but the desired output is = 2.
Is there any way i can make this work correct? please suggest.
NOTE : "55" is the input we are giving and consider the value "55,33,255,66,55" is from a database field.
Regards,
Balan
You want to match on ',55,', but there's the first and last position to worry about. You can use the trick of adding commas to the frot and back of the input to get around that:
select LENGTH('55,33,255,66,55') + 2 -
LENGTH(REPLACE(CONCAT(',', '55,33,255,66,55', ','), ',55,', 'xxx'))
Returns 2
I've used CONCAT to pre- and post-pend the commas (rather than adding a literal into the text) because I assume you'll be using this on a column not a literal.
Note also these improvements:
Removal of the cast - it is already numeric
By replacing with a string one less in length (ie ',55,' length 4 to 'xxx' length 3), the result doesn't need to be divided - it's already the correct result
2 is added to the length because of the two commas added front and back (no need to use CONCAT to calculate the pre-replace length)
Try this:
select CAST((LENGTH("55,33,255,66,55") + 2 - LENGTH(REPLACE(concat(",","55,33,255,66,55",","), ",55,", ",,"))) / LENGTH("55") AS UNSIGNED)
I would do an sub select in this sub select I would replace every 255 with some other unique signs and them count the new signs and the standing 55's.
If(row = '255') then '1337'
for example.

Extract specific words from text field in mysql

I have a table that contains a text field, there is around 3 to 4 sentences in the field depending on the row.
Now, I am making an auto-complete html object, and I would like to start typing the beginning of a word and that the database return words that start with those letters from the database text field.
Example of a text field: I like fishsticks, fishhat are great too
in my auto-complete if I would type "fish" it would propose "fishsticks" and "fishhat"
Everything works but the query.
I can easily find the rows that contains a specific word but I can't extract only the word, not the full text.
select data_txt from mytable match(data_txt) against('fish', IN BOOLEAN MODE) limit 10
I know it is dirty, but I cannot rearrange the database.
Thank you for your help!
EDIT:
Here's what I got, thanks to Brent Worden, it is not clean but it works:
SELECT DISTINCT
SUBSTRING(data_txt,
LOCATE('great', data_txt),
LOCATE(' ' , data_txt, LOCATE('great', data_txt)) - LOCATE('great', data_txt)
)
FROM mytable WHERE data_txt LIKE '% great%'
LIMIT 10
any idea on how to avoid using the same LOCATE expression over and over?
Use LOCATE to find the occurrence of the word.
Use LOCATE and the previous LOCATE return value to find the occurrence of the first space after the word.
USE SUBSTR and the previous 2 LOCATE return values to extract the whole word.
$tagsql ="SELECT * from mytable";
$tagquery = mysql_query($tagsql);
$tags = array(); //Creates an empty array
while ($tagrow = mysql_fetch_array($tagquery)) {
$tags[] = tagrow['tags']; //Fills the empty array
}
If the rows contain commas you could use -
$comma_separated = implode(",", $tags);
you can replace the comma for spaces if they are separated as spaces in your table.
$exp = explode(",", $comma_separated);
If you require your data to be unique you may include the following:
$uniquetags = array_unique($exp, SORT_REGULAR);
you can use print_r to see the results of the array resulting
Here array_merge is used because $rt will not get displayed if you are using a 'jquery' autocomplete else $rt may work and array_merge can be ignored. However, you may use array_merge to include multiple tables by repeating the previous process.
$autocompletetags = array_merge((array)$uniquetags);
This sorts the values in the alphabetic order
sort($autocompletetags, SORT_REGULAR);