I am developing an application, in one part of it I get a string as the phone number and I have to return the phone provider of that number, in database I have table prefix with this structure:
id , name, code
Some data in it is like:
(23242, 'UK-Mobile-T Mobile', '447984'),
(23243, 'UK-Mobile-T Mobile', '447985'),
(23244, 'UK-Mobile-T Mobile', '447986'),
(23245, 'UK-Mobile-T Mobile', '447987'),
(23246, 'UK-Mobile-Vodafone', '447407'),
(23247, 'UK-Mobile-Vodafone', '447423'),
name is the provider and code is the prefix belongs to that provider
and what I get as input is a phone number just like 447243xxxxx
Question is this:
how should I create a query to return the UK-Mobile-Vodafone as a result when the above input is given ?
please remember length of this code is not same for every country
This may work for you:
select t.*
from table t
where '447243xxxxx' like concat(t.code, '%');
This assumes, among other things, that only one prefix matches each number. Otherwise you need to choose among them.
If you need to choose among them, typically you would want the longest matching one:
select t.*
from table t
where '447243xxxxx' like concat(t.code, '%')
order by length(t.code) desc
limit 1;
And then, if you want to be able to use an index, you don't want to use concat() on the code. Instead, extract the first n characters. This is easy if all have the same length (6) as in your example:
select t.*
from table t
where left('447243xxxxx', 6) = t.code;
Just use the LIKE-operator with GROUP BY:
SELECT NAME FROM TBL_TABLENAME WHERE CODE LIKE '447243%' group by NAME;
Related
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'm trying to do a search of all the columns of a specific table and I want to return the result that contains certain characters. For example
Entered Search Value: "Josh"
Output Values: Josh, Joshua, Joshie, Rich Joshua
I want to return all values containing the characters Josh. I'm trying to use FreeTextTable however it only returns exact words like this
Entered Search Value: "Josh"
Output Values: Josh
I'm using the following code.
DECLARE #nameSearch NVARCHAR(100) = 'Josh';
SELECT MAX(KEY_TBL.RANK) as RANK, FT_TBL.ID
FROM Property FT_TBL
INNER JOIN (SELECT Rank, [KEY]
from FREETEXTTABLE(Property, *, #nameSearch)) AS KEY_TBL
ON FT_TBL.ID = KEY_TBL.[KEY]
GROUP BY FT_TBL.ID
I know this will be possible by using LIKE or CONTAINS but I have a lot of rows in that table and it would take time before it returns the result. So I need to use FreeTextTable to get the Rank and Key. However I can't achieve my goal here. I need help. Thanks!
I have a field called 'areasCovered' in a MySQL database, which contains a string list of postcodes.
There are 2 rows that have similar data e.g:
Row 1: 'B*,PO*,WA*'
Row 2: 'BB*, SO*, DE*'
Note - The strings are not in any particular order and could change depending on the user
Now, if I was to use a query like:
SELECT * FROM technicians WHERE areasCovered LIKE '%B*%'
I'd like it to return JUST Row 1. However, it's returning Row 2 aswell, because of the BB* in the string.
How could I prevent it from doing this?
The key to using like in this case is to include delimiters, so you can look for delimited values:
SELECT *
FROM technicians
WHERE concat(', ', areasCovered, ', ') LIKE '%, B*, %'
In MySQL, you can also use find_in_set(), but the space can cause you problems so you need to get rid of it:
SELECT *
FROM technicians
WHERE find_in_set('B', replace(areasCovered, ', ', ',') > 0
Finally, though, you should not be storing these types of lists as strings. You should be storing them in a separate table, a junction table, with one row per technician and per area covered. That makes these types of queries easier to express and they have better performance.
You are searching wild cards at the start as well as end.
You need only at end.
SELECT * FROM technicians WHERE areasCovered LIKE 'B*%'
Reference:
Normally I hate REGEXP. But ho hum:
SELECT * FROM technicians
WHERE concat(",",replace(areasCovered,", ",",")) regexp ',B{1}\\*';
To explain a bit:
Get rid of the pesky space:
select replace("B*,PO*,WA*",", ",",");
Bolt a comma on the front
select concat(",",replace("B*,PO*,WA*",", ",","));
Use a REGEX to match "comma B once followed by an asterix":
select concat(",",replace("B*,PO*,WA*",", ",",")) regexp ',B{1}\\*';
I could not check it on my machine, but it's should work:
SELECT * FROM technicians WHERE areasCovered <> replace(areaCovered,',B*','whatever')
In case the 'B*' does not exist, the areasCovered will be equal to replace(areaCovered,',B*','whatever'), and it will reject that row.
In case the 'B*' exists, the areCovered will NOT be eqaul to replace(areaCovered,',B*','whatever'), and it will accept that row.
You can Do it the way Programming Student suggested
SELECT * FROM technicians WHERE areasCovered LIKE 'B*%'
Or you can also use limit on query
SELECT * FROM technicians WHERE areasCovered LIKE '%B*%' LIMIT 1
%B*% contains % on each side which makes it to return all the rows where value contains B* at any position of the text however your requirement is to find all the rows which contains values starting with B* so following query should do the work.
SELECT * FROM technicians WHERE areasCovered LIKE 'B*%'
I'm trying to create a SQL query which will supply values for auto completion for a text field. Everything is working however I can't seem to create an SQL query which is exact enough for the purposes I want. I am using MySQL.
If there is a space (or multiple spaces) in the search term, I only want the query to do a LIKE comparison on the part of the string after the last space.
For example, say I have two possible values in the database:
Bolt
Bolts Large
Currently if the user types 'Bolt' then a space, both values above are returned using this query -
SELECT name FROM items WHERE name LIKE 'SEARCH_TERM%'
What I want is that if the user types 'Bolt' then a space, then only Bolt is returned from the database.
Effectively meaning that only the last part of the search term after the space is compared using LIKE, the results should match exactly up until the last space.
I've also tried:
SELECT name FROM items WHERE name LIKE 'SEARCH_TERM[a-z]%'
But that actually returns no results using the above scenario.
Is what I'm after possible? I've also tried to explore using Full Text Search but have had no look with that. I believe full text search is enabled on the name field, however I have limited experience with this. The query below didn't work.
SELECT name FROM items WHERE MATCH(name) AGAINST('SEARCH_TERM')
Any advice or points would be very appreciated.
The query
SELECT name FROM items WHERE name LIKE 'Bolt %'
doesn't return any record, because both 'Bolt' and 'Bolts Large' don't match 'Bolt %'.
SELECT name FROM items WHERE name LIKE 'Bolt%'
returns both records, because both 'Bolt' and 'Bolts Large' match 'Bolt%'.
To look for 'Bolt' and not 'Bolts', you must add a space to both your search string and the column string:
SELECT name FROM items WHERE concat(name, ' ') LIKE 'Bolt %'
returns 'Bolt' but not 'Bolts Large'.
SELECT name FROM items WHERE REPLACE(name, ' ', '') LIKE 'SEARCH_TERM%'
You could also use CONCAT and TRIM, or just trim
SELECT name FROM items WHERE name LIKE TRIM('SEARCH_TERM')
or your choice
SELECT name FROM items WHERE name LIKE CONCAT(TRIM('SEARCH_TERM'), '%')
SELECT name FROM items WHERE name LIKE CONCAT('%',TRIM('SEARCH_TERM'))
SELECT name FROM items WHERE name LIKE CONCAT('%',TRIM('SEARCH_TERM'), '%')
I have a table call objects which there are the columns:
object_id,
name_english(vchar),
name_japanese(vchar),
name_french(vchar),
object_description
for each object.
When a user perform a search, they may enter either english, japanese or french... and my sql statement is:
SELECT
o.object_id,
o.name_english,
o.name_japanese,
o.name_french,
o.object_description
FROM
objects AS o
WHERE
o.name_english LIKE CONCAT('%',:search,'%') OR
o.name_japanese LIKE CONCAT('%',:search,'%') OR
o.name_french LIKE CONCAT('%',:search,'%')
ORDER BY
o.name_english, o.name_japanese, o.name_french ASC
And some of the entries are like:
Tin spoon,
Tin Foil,
Doctor Martin Shoes,
Martini glass,
Cutting board,
Ting Soda.
So, when the user search the word "Tin" it will return all results of these, but instead I just want to return the results which specific include the term "Tin" or displaying the result and rank them by relevance order. How can I achieve that?
Thanks.
You can use MySQL FULLTEXT indices to do that. This requires the MyISAM table type, an index on (name_english, name_japanese, name_french, object_description) or whatever fields you want to search on, and the appropriate use of the MATCH ... AGAINST operator on exactly that set of columns.
See the manual at http://dev.mysql.com/doc/refman/5.5/en/fulltext-search.html, and the examples on the following page http://dev.mysql.com/doc/refman/5.5/en/fulltext-natural-language.html
After running the query above , you will get all sort of results including ones that you are not interested, but you can then use regular expressions on the above results(returned by mysql server) set to filter out what u need.
This should do the trick - you may have to filter out duplicates, but the basic idea is obvious.
SELECT
`object`.`object_id`,
`object`.`name_english`,
`object`.`name_japanese`,
`object`.`name_french`,
`object`.`object_info`, 1 as ranking
FROM `objects` AS `object`
WHERE `object`.`name_english` LIKE CONCAT(:search,'%') OR `object`.`name_japanese` LIKE CONCAT(:search,'%') OR `object`.`name_french` LIKE CONCAT(:search,'%')
union
SELECT
`object`.`object_id`,
`object`.`name_english`,
`object`.`name_japanese`,
`object`.`name_french`,
`object`.`object_info`, 10 as ranking
FROM `objects` AS `object`
WHERE `object`.`name_english` LIKE CONCAT('%',:search,'%') OR `object`.`name_japanese` LIKE CONCAT('%',:search,'%') OR `object`.`name_french` LIKE CONCAT('%',:search,'%')
ORDER BY ranking, `object`.`name_english`, `object`.`name_japanese`, `object`.`name_french` ASC