I'm working on a faceted search in Coldfusion and SQL. I've tried creating a query like this:
SELECT * FROM Turbos
WHERE
PartNumber LIKE '%#trim(SearchCriteria)#%'
OR PartDescription LIKE '%#trim(SearchCriteria)#%'
AND (PumpingSpeed BETWEEN #minimum# AND #URL.speed#)
AND InletFlange LIKE '#URL.inlet#'
AND Bearing LIKE '#URL.bearing#'
AND Condition LIKE '#URL.condition#'
The problem is the server is returning rows that don't contain EVERY piece of data I'm supplying. How can I select ONLY those rows which contain all the criteria?
just wrap the OR bit in brackets:
(PartNumber LIKE '%#trim(SearchCriteria)#%' OR PartDescription LIKE '%#trim(SearchCriteria)#%') AND...
at the moment you have A or B and C which is being read as A or (B and C). You want (A or B) and C.
And make sure you use cfqueryparam as suggested above.
Just a guess really, but change
...'%#trim(SearchCriteria)#%' OR
PartDescription ...
to
...'%#trim(SearchCriteria)#%' AND
PartDescription ...
edit
or are you saying some have null values?
post comment edit
Imagine for example that InletFlange is empty for your part, and the user didn't put it in their search.
Then InletFlange LIKE '#URL.inlet#' will compare "" LIKE "", which is of course true, so the product shows up.
There are many ways to solve this. For example
Default the search criteria to "N/A" or something
Default the column in the database in a similar fashion.
something along the lines of AND NOT ISNULL(InletFlange,'')=='' for each criteria
Okay, I found the answers:
Leigh: +1 to clarifying the question. (It is
unlikely this has any bearing on the
results, but what is the point of
using LIKE without wildcards "%"? If
it is an equality comparison you are
after, just use equals ie ... AND
Condition = '#URL.condition#' )
You were quite right, I was missing the percent symbols in my LIKE comparisons (DUH!). I removed them earlier thinking they were the problem, but they weren't, this was:
Aiden: just wrap the OR bit in brackets:
(PartNumber LIKE '%#trim(SearchCriteria)#%' OR PartDescription LIKE '%#trim(SearchCriteria)#%') AND...
Thank you Aiden!
While this isnt an answer to your question - you might want to consider using a dedicated search solution such as Solr (which is included with CF9). Its a more powerful fulltext solution than just raw SQL and includes facetting
Related
I am trying to find special characters in any of my fields that are not in the range of a-zA-Z0-9. However if I try this query:
select Name from table where Name like '%[?]%'
I get two records:
???? ?????
Fixed?????
Which is what I want. However, since I don't know what the special chars will be I need to use an exclusion of data that has mixed characters:
select Name from table where Name NOT like '%[a-zA-Z0-9]%'
Since this excludes all records with a-zA-Z0-9 I only get:
???? ?????
But I also need to get the 'Fixed?????' result. I need to get the data that has the special character merged into it.
I am bit at a loss as how to do this. I've seen this done with shell scripts or 'vi' (LIST), but in SQL that's not so easy.
Has anyone out there solved this?
Try this code:
select Name from table where Name like '%[^0-9a-zA-Z ]%'
Thank you for replying. I had tried your suggestions but I was still getting more results. However, it looks like you can get very specific with the exclusion. Eventually I ended up adding results from the data I got.
Like this:
select Name from table where Name LIKE '%[^0-9a-zA-Z() -._/\:=,]%'
This finally gave me what I was looking for. Although new issue I have now is how to suppress the [] brackets which apparently also are found in the data:
???? ?????
HP PCI 10/100Base-TX Core [100BASE-TX,FD,AUTO,TT=1500]
Fixed?????
Adding those brackets into the query breaks the array boundary:
'%[^0-9a-zA-Z() -._/\:=,**[]**]%'
However, this is something I can handle. As long as I am not getting "all" the data.
LIKE '%[^0-9a-zA-Z]%'
numbers (0-9), lowercase alphas (a-z), uppercase alphas (A-Z). The "^" makes that a "NOT" one of these things
I have to write a select statement following the following pattern:
[A-Z][0-9][0-9][0-9][0-9][A-Z][0-9][0-9][0-9][0-9][0-9]
The only thing I'm sure of is that the first A-Z WILL be there. All the rest is optional and the optional part is the problem. I don't really know how I could do that.
Some example data:
B/0765/E 3
B/0765/E3
B/0764/A /02
B/0749/K
B/0768/
B/0784//02
B/0807/
My guess is that I best remove al the white spaces and the / in the data and then execute the select statement. But I'm having some problems writing the like pattern actually.. Anyone that could help me out?
The underlying reason for this is that I'm migrating a database. In the old database the values are just in 1 field but in the new one they are splitted into several fields but I first have to write a "control script" to know what records in the old database are not correct.
Even the following isn't working:
where someColumn LIKE '[a-zA-Z]%';
You can use Regular Expression via xQuery to define this pattern. There are many question in StackOverFlow that talk about patterns in DB2, and they have been solved with Regular Expressions.
DB2: find field value where first character is a lower case letter
Emulate REGEXP like behaviour in SQL
My question seems to be quite simple, but I'm worried the answer might actually be somewhat complex. I am trying to perform a simple Select query that behaves like the following.
Here is the code:
SELECT * FROM tbl_tbl WHERE tbl_tbl.colA LIKE '%foo%' OR tbl.tbl.colA LIKE '%oof%' AND
tbl_tbl.colB LIKE '%bar%' OR tbl_tbl.colB LIKE '%rab%'
So I am just searching for 4 strings (2 in each column), and if I find one in each pair, I want to show that entire entry.
Mathematically, it makes quite a bit of sense to me.
I want to do (This OR That) AND (One OR Another) where any combination of This/One, This/Another, etc. passes the expression.
Pretty simple right?
How do I tell SQL to work right (you know, like that obscure way in my mind)?
Currently, I'm getting entries out of my table where only 1 of the column disciplines match, and that's not giving me the specificity of the priority I am looking for.
You would express it using parentheses and boolean logic in the where clause:
SELECT *
FROM tbl_tbl t
WHERE (t.colA LIKE '%foo%' OR t.colA LIKE '%oof%') AND
(t.colB LIKE '%bar%' OR t.colB LIKE '%bar%');
Do note that this is based on your example in the question. The second clause of the AND has two conditions that are the same. I assume this is a typo in the question, but not knowing the right pattern, I've left it in the answer.
I would like to create a SQL query, which does the following..
- I have a few parameters, for instance like "John","Smith"
- Now I have a articles tables with a content column, which I would like to be searched
- Now, How can I find out the rows in the articles table, which has the any one of those values("John","Smith")
I cannot use content LIKE "%john% or content LIKE "%smith%", as there could be any number of incoming parameters.
Can you guys please tell me a way to do this....
Thanks
Have you considered full-text search?
While HLGEM's solution is ideal, if full-text search is not possible, you could construct a regular expression that you could test only once per row. How exactly you do that depends on the DBMS you're using.
This depends a lot on the DBMS you're using. Generally - if you don't want to use full-text search - you can almost always use regular expressions to achive this goal. For MySQL see this manual page - they even have example answering your question.
If full text search is overkill, consider putting the parameters in a table and use LIKE in theJOIN` condition e.g.
SELECT * -- column list in production code
FROM Entities AS E1
INNER JOIN Params AS P1
ON E1.entity_name LIKE '%' + P1.param + '%';
I want to show the closest related item for a product. So say I am showing a product and the style number is SG-sfs35s. Is there a way to select whatever product's style number is closest to that?
Thanks.
EDIT: to answer your questions. Well I definitely want to keep the first 2 letters as that is the manufacturer code but as for the part after the first dash, just whatever matches closest. so for example SG-sfs35s would match SG-shs35s much more than SG-sht64s. I hope this makes sense whenever I do LIKE product_style_number it only pulls the exact match.
There normally isn't a simple way to match product codes that are roughly similar.
A more SQL friendly solution is to create a new table that maps each product to all the products it is similar to.
This table would either need to be maintained manually, or a more sophisticated script can be executed periodically to update it.
If your product codes follow a consistent pattern (all the letters are the same for similar products, with only the numbers changing), then you should be able to use a regular expression to match the similar items. There are docs on this here...
It sounds like what you want is levenshtein distance .
Unfortunately, there isn't a built-in levenshtein function for mysql, but some folks have come up with a user-defined function that does it(deadlink).
You will probably want to do it as a stored procedure, as I expect that the algorithm may not be trivial.
For example, you may split the term at the -, so you have two parts. You do a LIKE query on each part and use that to make a decision.
You could just loop though, replacing the last character with "%" until you get at least one result, in your stored procedure.
Sounds like you need something like Lucene, though i'm not sure if that would be overkill for your situation. But it certainly would be able to do text searches and return the ones most similar first.
If you need something more simple I would try to start by searching with the full product code, then if that doesn't work try to use wildcards/remove some characters until you return a result.
JD Isaacks.
This situation of yours is very simple to solve.
It`s not like you need to use Artificial Intelligence like the Google.
http://www.w3schools.com/sql/sql_wildcards.asp
Take a look at this manual at w3schools about wildcards to use with your SELECT code.
But also you will need to create a new table with 3 columns: LeftCode, RightCode and WildCard.
Example:
Rows on Table:
LeftCode = SG | RightCode = 35s | WildCard = SG-s_s35s
LeftCode = SG | RightCode = 64s | WildCard = SG-s_t64s
SQL Code
If the user typed the code that matches the row1 of the table:
SELECT * FROM PRODUCTS WHERE CODE LIKE "$WildCard";
Where $WildCard is the PHP variable containing the column 3 of the new table.
I hope I helped, even 4 years late...