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
Related
I am working on a report that displays patient names (as groups with drilldowns) and several fields related to their visits. I have created a column in the report to display whether or not a specific value appears in the 'LocationID' column. The expression I used is
=IIF(Fields!LocationID.Value="WELL","Y","N")
I thought this was working great, it displays Y or N next to each name to let me know if 'WELL' was in their 'LocationID'. I checked several to ensure that this was going to work and discovered that there was a LocationID code of 'WHS' and since I have the rows ordered by Name and LocationID if there was a WHS visit it shows up at the top of the group and my expression is only seeing this top item. How can this expression be written differently so that it searches the entire result of each group? Depending on the date range a patient may have one visit or they may have ten. I need to check all visits that are returned. Perhaps there is a better method. Thanks in advance.
I agree with jimmy8ball that the easiest way to solve most issues like this is to push some logic back into the SQL layer.
However, if you really want to do this via SSRS functionality, then you could implement a substring search against a lookupset. Assuming you have a patient id in your dataset that is unique for each patient (I hope your group isn't on the name) then...
=Iif(InStr(Join(Lookupset(Fields!patientid.Value, Fields!patientid.Value, Fields!LocationsID.Value, "dataset"), ","), "WELL") > 0, "Y", "N")
Which says, "Search through the dataset for all rows related to my patientid, join every location into a comma deliminated string, search the string for the text "WELL" and return "Y" if it's found.
Obviously if you have locations in your dataset like "WELLY", these will become false positives and you'll have to implement some more nested logic. Try appending a value (perhaps !) to the lookupset return field so that you can search for "WELL!" or some other terminator character.
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]%;
I am trying to build a query which will look at the data in two fields in two different tables and check to see if the data is the same, if it is I want it to return the number of times it is matched, if it isn't I simply want it to return the text saying "No viewings".
I have constructed this query in my access database which has the field from the first table "Property" and the second field I want it to compare the data with, "Viewings". I have build the following expression using the build tool, however I am stuck to make it work since every time I get this error message when trying to run the query: "Your query does not include the specified expression 'Property Viewed' as part of an aggregate function."
totalViewings: IIf([Viewings]![Property Viewed]=[Property]![ID],Count([Viewings]![Property Viewed]=[Property]![ID]),"No Viewings")
Any help how to overcome this error would be very appreciated.
Thanks
I would suggest doing something like this:
1) Assuming this is something you are developing yourself, make sure your data structure is all in order first. Since I dislike relatively code-hostile identifiers, I'd have the tables as so -
Properties - PropertyID (AutoNumber, primary key), HouseNumberOrName, Street, etc.
Viewings - ViewingID (AutoNumber, primary key), PropertyID (Number/Long Integer), ViewingDate, etc.
In the Relationships view, Properties.PropertyID would then be set up to point to Viewings.PropertyID in a one-to-many relation.
2) Your actual query I would then break into two, the first to compile the data and the second to format it for display. The first would go like this, saved as ViewingCounts...
SELECT Properties.PropertyID, Count(Viewings.PropertyID) As ViewingCount
FROM Properties LEFT JOIN Viewings ON Properties.PropertyID = Viewings.PropertyID
GROUP BY Properties.PropertyID;
... and the second like this, saved as ViewingCountsForDisplay:
SELECT Properties.*, IIf(ViewingCount = 0, 'No viewings', ViewingCount) AS Viewings
FROM Properties INNER JOIN ViewingCounts ON Properties.PropertyID = ViewingCounts.PropertyID
ORDER BY Properties.PropertyID;
Let's consider a multiple selection parameter on a report: Employee
This parameter has a lot of possible values. Initially nothing is shown on the list and there is a textfield search parameter associated, that updates the Employee selection list with top n matches for the searched string.
If the entered search query is John Doe we can imagine that now the selection list shows:
John Doe
...
Xavier John Doesson
Now I can select as many items as I want from this filtered list, but if I want to select both John Doe and Alicia Keys happens the following:
First when I enter the search string "John Doe" the selection list gets populated accordingly
I select John Doe - OK
I enter search string "Alicia Keys", the selection list gets populated also
Selection of John Doe is gone - I want to be able to select both Alicia and John at the same time, but I don't want to go through a thousands of names long selection list
Update:
Forgot to mention that we have an OLAP cube in the background with dimension 'Employee'. This dimension is used as the source of the parameter and the param dataset uses MDX to fetch the values, therefore the SQL solution cannot be applied here.
The current solution creates an custom set with MDX Filter and Head functions and then this set is used in the ROWS-part of the MDX query.
Here is how the set created:
SET setEmployees AS {
HEAD(
FILTER( [Employees].[Employees].ALLMEMBERS,
INSTR([Employees].[Employees].CURRENTMEMBER.Name,#EmployeeSearch,1 >= 1 )
)
,100)
}
Basically the problem with this solution is that how do you add multiple search strings to the instr function
Is there a common solution to this kind of situation? Am I approaching the problem from wrong direction?
What you could do is make the search parameter more flexible, so you can handle input such as:
John OR Jane
If "OR" queries are more common than "AND" queries you could support it with queries such as:
John Jane
Note that this may throw people off, because the search features they're used to (such as Google search) typically tend interpret multiple words in the "AND" sense.
Anyhow, the tricky bit of course is the SQL behind the Employee data set. This should use the search parameter in a more flexible way. You haven't specified how that's currently working, but I imagine you may be using something like:
WHERE Employee.FullName LIKE '%' + #SearchParameter + '%'
You would need to extend that to support "OR" queries. There's a whole range of solutions for that, from quick 'n dirty handmade SQL (e.g. string split combined with WHERE...IN) to full-text querying. Choose a solution that's best for your situation.
If you have a fixed number of search terms than you can do something like the following.
FILTER( [Employees].[Employees].ALLMEMBERS,
INSTR([Employees].[Employees].CURRENTMEMBER.Name,#EmployeeSearch1,1 >= 1) OR
INSTR([Employees].[Employees].CURRENTMEMBER.Name,#EmployeeSearch2,1 >= 1)
)
Even if you can do that, I do not recommend it. You don't have the luxury to index Analysis Services like you do SQL. A better possible approach would be to query your data warehouse for the employees and return the appropriate keys, and then filter by those keys in your MDX statement.
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(" ","%");