I have an ajax-search on a mysql-db. Example: Search for "man" which I query with:
SELECT id FROM table WHERE name LIKE '%man%;
I now want to sort the result to have all results starting with the search in alphabetical order:
man
mankind
after that I want to have all results width the search INSIDE in alphabetical order, like:
iron man
woman
How can I do that?
You can order by the position of your search term in the string:
SELECT id
FROM table
WHERE name LIKE '%man%'
ORDER BY INSTR(name, 'man'), name
See also: INSTR(), LOCATE()
You could also change the expression to only distinguish between start of the string or anywhere else:
ORDER BY IF(INSTR(name, 'man'), 1, 0)
You can construct your ORDER BY using a CASE statement to verify the substrings. Note: I am using UPPER() here to convert both the search value and the column value to uppercase, for a case-insensitive match. If that is not your need, remove the UPPER().
ORDER BY
CASE
/* Matches the start of the string */
WHEN UPPER(LEFT(name, 3)) = 'MAN' THEN 1
/* Doesn't match the end or the start (in the middle) */
WHEN UPPER(RIGHT(name, 3)) <> 'MAN' THEN 2
/* Matches the end of the string */
WHEN UPPER(RIGHT(name, 3)) = 'MAN' THEN 3
ELSE 4
END,
/* Then order by the name column */
name
This method should be fairly portable, but I like the INSTR() answer below better.
Try this
SELECT id FROM table WHERE name LIKE 'man%';
UNION
SELECT id FROM table WHERE name LIKE '%man%';
Related
A table, named strings, contains various strings, and unique id's:
Question is, how to write a query that takes an input string, and return the id of the longest matching (sub) string in the strings table?
The matching string, may, or may not be a substring of the input string. Comparison starts at string index 0.
Inputs and expected output:
INPUT -> OUTPUT
ABC -> 1
ABCD -> 2
ABCKK -> 1
ABCDDD -> 2
DAB -> NULL
CDE -> NULL
Doing this:
SET #theString = 'ABCBBB';
SELECT id FROM strings WHERE a_string LIKE #theString;
only returns the correct result when the input string exactly matches a string in the table, and don't work when the 'a_string' is a substring.
You can use:
select s.*
from strings s
where #theString regexp a_string
order by length(a_string) desc
limit 1;
In regards of using LIKE, you need to set the wildcards for it to work as the filter you want. If you are not required to set a variable, you can use the following query.
SELECT id FROM strings
WHERE a_string LIKE '%ABC%'
ORDER BY length(a_string) DESC LIMIT 1;
or if you need a variable, it can be done with the CONCAT function
SELECT id FROM strings
WHERE a_string LIKE CONCAT('%',#theString,'%')
ORDER BY length(a_string) DESC LIMIT 1;
This just is an alternative to #Gordon Linoff's answer.
I want SQL to show / order the results for the column name first then show results for the description column last.
Current SQL query:
SELECT * FROM products WHERE (name LIKE '%$search_query%' OR description LIKE '%$search_query%')
I tried adding order by name, description [ASC|DESC] on the end but that didn't work.
It's for optimizing the search results. If a certain word is found in description it should go last if a certain word is also found in the name column.
You can use a CASE statement in an ORDER BY to prioritize name. In the example below all results where name is matched will come first because the CASE statement will evaluate to 1 whereas all other results will evaluate to 2.
I'm not sure by your problem description what exactly you want the behavior to be, but you can certainly use this technique to create more refined cases to prioritize your results.
SELECT *
FROM products
WHERE (name LIKE '%$search_query%' OR description LIKE '%$search_query%')
ORDER BY CASE WHEN name LIKE '%$search_query%' THEN 1 ELSE 2 END
If you want the names first, the simplest order by is:
order by (name like '%$search_query%') desc
MySQL treats booleans as numbers in a numeric context, with "1" for true and "0" for false.
While this is undocumented, when results sets combined by a UNION ALL and not sorted afterwards, they stay in the order returned, as UNION ALL just adds new results to the bottom of the result set. This should work for you:
SELECT * FROM products
WHERE name LIKE '%$search_query%'
UNION ALL
SELECT * FROM products
WHERE (description LIKE '%$search_query%' AND name NOT LIKE '%$search_query%')
I wonder if its possible to sort a result so that if a column contains a spesific word ('misc'), it will come out last?
current query:
select * from table order by name asc
current result:
banjo
guitar
miscproduct1
miscproduct2
piano
pseudocode:
select * from table order by name asc,
except if name like '%misc%' then sort it last
pseudo result:
banjo
guitar
piano
miscproduct1
miscproduct2
Is this possible?
You could use LOCATE() as the first ordering argument:
ORDER BY LOCATE('misc', name), name;
The LOCATE() function returns 0 if the search string can't be found in the subject, and yields a positive integer if it is found.
To normalize the sorting for subjects that contain the search you can combine with LEAST():
ORDER BY LEAST(LOCATE('misc', name), 1), name;
You can use a CASE in the ORDER BY clause.
SELECT colName
FROM table
ORDER BY
CASE WHEN colName LIKE 'misc%'
THEN concat('zzz',colName)
ELSE colName
END
Demo: http://sqlfiddle.com/#!2/6e08c/7
I have a table like:
id name
--------
1 clark_009
2 clark_012
3 johny_002
4 johny_010
I need to get results in this order:
johny_002
clark_009
johny_010
clark_012
Do not ask me what I already tried, I have no idea how to do this.
This will do it, very simply selecting the right-most 3 characters and ordering by that value ascending.
SELECT *
FROM table_name
ORDER BY RIGHT(name, 3) ASC;
It should be added that as your data grows, this will become an inefficient solution. Eventually, you'll probably want to store the numeric appendix in a separate, indexed integer column, so that sorting will be optimally efficient.
you should try this.
SELECT * FROM Table order by SUBSTRING(name, -3);
good luck!
You may apply substring_index function to parse these values -
select * from table order by substring_index(name, '_', -1)
You can use MySQL SUBSTRING() function to sort by substring
Syntax : SUBSTRING(string,position,length)
Example : Sort by last 3 characters of a String
SELECT * FROM TableName ORDER BY SUBSTRING(FieldName, -3);
#OR
SELECT * FROM TableName ORDER BY SUBSTRING(FieldName, -3,3);
Example : Sort by first 3 characters of a String
SELECT * FROM TableName ORDER BY SUBSTRING(FieldName, 1,3);
Note : Positive Position/Index start from Left to Right and Negative Position/Index start from Right to Left of the String.
Here is the details about SUBSTRING() function.
If you want to order by the last three characters (from left to right) with variable name lengths, I propose this:
SELECT *
FROM TABLE
ORDER BY SUBSTRING (name, LEN(name)-2, 3)
The index starts at lenght of name -2 which is the third last character.
I'm a little late but just encountered the same problem and this helped me.
Say I have a table similar to:
ID Name
1 Test
2 Contest
3 Fittest
4 Testament
Is there a MySQL query I could use with ordering to allow it to display a specific word first?
For example, users are searching for the word "Test". I have a statement similar to "SELECT * FROM table WHERE NAME LIKE '%Test%'". Could I display results to show things that START with Test begin first followed by everything else, while everything is still in alphabetical order.
So output would be:
Test
Testament
Contested
Fittest
Thanks.
This will put your words that begin with Test at the top, and sort those words plus the remainder of the list in alphabetical order..
SELECT * FROM mytable
ORDER BY CASE WHEN name LIKE 'test%' THEN 0 ELSE 1 END ASC, name ASC
SELECT * FROM table
WHERE NAME LIKE '%Test%'
order by case when name like 'test%' then 0 else 1 end