Searching Mysql for similar string - mysql

People have different ideas of how to search for the same term.
For example Tri-Valley, Trivalley, Tri Valley (and possibly even incorrect spellings)
Currently that search is done like this
SELECT * FROM `table` WHERE `SchoolDistrict` LIKE '%tri valley%';
Is there an easy way to say 'space dash or no space' without writing out three like statements?
It seems like it could easily be done:
SELECT * FROM `table` WHERE `SchoolDistrict` LIKE '%tri%valley%';
But this only works if the initial input is 'tri-valley' or 'tri valley' If the initial input is 'trivalley' I have no idea where to place the % (theoretically that is, actually, I do, as we are only looking at about a dozen different school districts, but I'm looking to solve the larger problem)

You could consider using SOUNDEX, or SOUNDS LIKE if you have a lot of incorrect spellings. If you've got a lot of rows (or even if you don't), it might be wise to store the output of the SOUNDEX in an additional column.
I'd also recommend -- in the interests of accuracy -- introducing a separate table with an authoritative list of school districts, and run a query to find those which aren't in that list.

MySQL has a function called Sounds like.
link text

An alternative here is to recast the problem from search to select, if possible. Instead of letting your users enter free-form text to choose a school district, if you have a set of school districts generate a dropdown (or set of cascading dropdowns if the list is large, say by county, then by school district) and allow the user to select the appropriate one. Use this both for "searching" and for data entry to eliminate non-canonical entries. Obviously this only works when you can enumerate all of the entries.
Alternatively you could allow the user to choose a starts with or contains type search and simply generate the appropriate SQL ('tri%' or '%tri%') based on the selected search type. If the user understands that the search type is starts with or contains, they will likely adjust their search string until it yields the results they need.

The second statement you posted should do the trick:
SELECT * FROM 'table' WHERE 'SchoolDistrict' LIKE '%tri%valley%';
What you should do before you pass the search term into the select statement is to replace all characters and spaces with the % sign. For example,
SearchTerm = SearchTerm.Replace(" ","%");

Related

Extracting words from a paragraph and then match with existing database by Ms Access

I am the beginner on the usage of MS Access.
I am going to build a program in the MS Access 2007 which can scanning some specific wordings listed in the data table from a paragraph.
For example, I want to know the occurrences of the transportation taken by the students.
(i) Therefore, I set the words "school" and "Bus" in my datatable [tableA] fields [trans].
(ii) Then, I input "I go to school by bus." in the [Input] boxes.
(iii) The result i want is that the sun of occurrences of both "school" and "Bus" can be showed in the another one textbox.
In the current situation, i just create a query [QueryA] from the [tableA] and directly use the count function in the query form. And then set the criteria as " Like [forms]![tableA]![Input] & "*" ".
However, it can just match the words in the [Input] with the final count result of the Query.
Ths a lot for providing any advice, including new direction.
I hope I understand what you're asking here, so I'll give it a stab with the information that you've provided. In your SQL window, try the following script: NOTE: You will need to change the WHERE clause to reflect your Input box(s)
SELECT Count(*) AS Expr1
FROM tableA
WHERE tableA.[trans] Like '%[Input]%;

Using LIKE in sql query

In a query in which I am looking for results based on the title of articles, I use the LIKE part as followed:
WHERE title LIKE %searchquery%
In my database one title is like this:
Economy in America
My problem:
With my current query, this title does NOT get listed, when the user enters the following searchquery:
america economy
When the user enters only one of these terms, everything works fine and the title gets listed.
How come?
How do I need to adjust my query so that my sql query will also work when the user enters more than one term?
The MySQL LIKE operator is limited in that it doesn't offer full regex support of the sort for which you are really looking. That being said, one option you could try would be to split your search query terms and then join multiple LIKE conditions using AND. Consider this example:
WHERE title LIKE %queryterm1% AND LIKE %queryterm2%
If queryterm1 be 'america' and queryterm2 be 'economy', then this would match the title 'Economy in America'.
You will need to split the query by whitespaces and then add multiple LIKE statements like this:
WHERE title LIKE '%america%' AND title LIKE '%economy%'
As #Tim says, you must write some routine in your application to divide the string terms and inject them in the select where clause. Or you may need to write some stored procedure for that.

MySQL conditional variable inside text field

This might seem like a strange one, but can you store a conditional variable inside a text field (or something that can be made to work like one)?
I'm creating a notification system that groups notification by date and type, so if 2 or more of the same type are created in the same day it will group the notifications together and provide a count (e.g. Person1 and 3 others have done something).
The notification messages are stored in a table as a template e.g.
[[value]] has just done something
[[value]] is then replaced with Person1's name (and count OTHERS) by using
REPLACE(t1.message,
'[[value]]',
IF(t1.value_as_user=1,
CONCAT(t1.forename, ' ', t1.surname, IF((count((t1.id + DATE(t1.date)))-1)<>0,
CONCAT(' and ', (count((t1.id + DATE(t1.date)))-1), ' other'),
'')),
t1.value)) as 'message'
The only problem with this is it would mean that grammatically the message would no longer make sense i.e. "Person1 and 2 others has just done something" should now be "Person1 and 2 others have just done something"
Is there a way to select a string within a text field (like I have done with [[value]]) except have it where it would be something like [[has/have]] and depending on the count the correct one could chosen?
Sometimes you can change the sentence to avoid the grammatical variability:
Something has been done by Person1 and 2 others
(If you read The Elements of Style by Strunk & White, you may be conditioned to recoil at the passive voice. The above trick may seem like cheating. But don't let them bully you.)
Otherwise, no, there's no function in MySQL that can analyze a string and find out its grammatical usage in English and automatically conjugate verbs.
You could make [[has/have]] be another meta-field in your string, and then replace it with another expression based on the count.
But frankly, I wouldn't do the string formatting in an SQL expression. Not only for this reason, but because string-manipulation in SQL is clumsy compared to literally any other language (except Java of course).

MYSQL Query to compare the results of two queries?

I am currently working on a search feature for a website that searches through a database for a specific animal.
Say the user inputs rabbit, the search will go through the db and display the results for rabbit.
Now say a user inputs bunny the search will go through the db but will not find a match for bunny.
Most people know that bunny means rabbit, but the database doesn't know that. At this point I have implemented a MySQL thesaurus within the same database to search for synonyms of what the user inputs.
This means that if the user inputs bunny it will display a list of synonyms for bunny.
In that list there is the word Rabbit and I am trying to pull that word out of there to generate a match. At this point I have the following.
"SELECT `engname` FROM `searchtestdb` WHERE `engname` IS NOT NULL ";
-- This displays the english name of every animal within that table. --
"SELECT synonyms.* FROM words LEFT JOIN synonyms ON synonyms.word_id = words.word_id WHERE word = \"$searchBox\""
-- This displays the synonyms for $searchBox which is the word the user inputs. --
Both of these queries display what I want them to display. In other words, the first query gives me all of the animals names in the table, and the second query gives me the synonyms for the word the user inputed.
At this point my problem is how to compare the synonyms to all the animals names. I've tried several queries with the LIKE command but I keep getting syntax errors.
Is what I am asking possible? If not what would be a better course of action? Any help would be greatly appreciated.
Thank You.
I got a semi fiddle going for y'all.
http://sqlfiddle.com/#!2/47d42/3
It only works for "bunny" since the entire synonym and word list is too big for fiddle.
select * from searchtestdb
where engname in
(
SELECT synonyms.synonym
FROM words
LEFT JOIN synonyms ON synonyms.word_id = words.word_id
WHERE word = "bunny"
)
SQLFIddle
EDIT: Since you probably also want to search for word directly inputted and not just it's synonyms, you should also add that condition:
OR engname = "bunny"
SQLFIddle
I think the idea is this: (pseudocoded)
Create a function which returns true or false (with a parameter as the search word) of whether there exists a result. This is a basic
SELECT COUNT > 0 FROM table WHERE text LIKE %parameter%
Now create a function that returns a table of results:
loop through the the synonyms of the word which again comes as a
parameter to this function
add to table of the results if a synonym in a loop fits the function above.
return the table

Variation of SELECT * - all columns except those explicitly referenced

Is there any way to convert one column and be able to reference all the other columns without naming them explicitly?
Normally I would do this:
SELECT
,[Id]
,[Name]
,CONVERT(VARCHAR(10),[CreateDate], 104) as [CreateDate]
FROM Customers
What I could do in the perfect world would be:
SELECT
*
,CONVERT(VARCHAR(10),[CreateDate], 104) as [CreateDate]
FROM Customers
Where * would mean all columns that are not explicitly stated in the query.
Is there a keyword that enables one to do this or is there some other way? Please keep in mind that it has to be doable in a query - no changing tables, making views, SPs or something else.
There isn't a programmatic way to say "all the columns except this one" unless you wanted to build dynamic SQL from sys.columns based on a list you provide the query (it would be very difficult to derive the list of referenced columns from the query dynamically, especially as you introduce joins, where clauses, etc).
But there is a pretty trivial way to do this without typing them all. Just expand your table in Object Explorer, and drag the "Columns" node onto the query editor window. Now just remove the CreateDate column from the list.
What I like to do to avoid typing a long list of fields is select the table name in the editor and then press alt-f1. That is the same thing than typing "sp_help table". You will get a result set with all the column names of that table. I copy that list into the editor and add the commas.
An easy way to add commas at the end of all the lines by using the search and replace in the editor:
Select only the lines with the column name.
Check "Use" and select "Regular Expressions" from the drop down.
In the "Find What" type $ (Dollar sign means end of the line)
in the "Replace With" type ,
That will add a comma to the end of each selected line.
Another way is to right click on the table in the Object Explorer and click on "select top 1000" option that will create a script for you in another text editor window.