Ordering Sql result based on number of token matches from RLIKE - java

I am trying to implement a simple search query, where I am splitting the search text into tokens and then returning all results that contain any of the tokens, I am using RLIKE 'token1|token2|token3|...', this is working correctly and returning all the result, but now I would want to Order the result by the numbers of tokens from the RLIKE that matches, is that anyway possible anyway? thanks in advance.
SELECT p.* FROM product p
WHERE p.title RLIKE 'token1|token2|token3';

You can use the operator LIKE for each of the tokens in the ORDER BY clause:
ORDER BY (p.title LIKE '%token1%') +
(p.title LIKE '%token2%') +
(p.title LIKE '%token3%') DESC
Each of the boolean expressions p.title LIKE '%tokenX%' evaluates to 1 for true or 0 for false.

Related

KNIME: Compare if One Column Contains a subset of another column

In Knime I am trying to compare if a value in one column is contained within another column. I tried to do this using "LIKE" in the Rule Engine but couldn't get the wildcards to work with a column input instead of a string. E.g.
For row1 I want to check if column 1, row 1 is within column 2, row 1
For row2 I want to check if column 1, row 2 is within column 2, row 2
Like is "ABC" contained within "test ABCtest"
Does the "LIKE" in Rule Engine only allow hard coded strings for comparison? Other ideas to achieve this? Thank you for the help!
The String Manipulation node with the regexMatcher can help here, though the result will be String (with values True/False by default), so further node will be required if for example a number is required (if different String, you can use the ?/: ternary operator like == "True" ? "when true" : join("when false it was because '", $columnReference$, "' was not found")).
You can use regexMatcher like this (\Q/\E helps to avoid treating the content in Reference column as a regular expression (except when it contains \E)):
regexMatcher($text$, join(".*?\\Q", $Reference$, "\\E.*+")) == "True" ? "vrai" : "faux"
Rule engine allows wildcards with LIKE operator but it does not allow wildcards combined with columns meaning the following will work fine:
$column1$ LIKE "*test*" => "1"
The following is allowed as well but will not work fine:
$column1$ LIKE "*$column2$*" => "1"
The reason is when you got double quotes $ is not recognized so you do not get the values from column2. Instead you get same string each time: "*$column2$*" which is not what you want.
Additionally you can use indexOf() function in String Manipulation or Column Expressions node that will return the first position of string value from column1 in column2. If not found the function will return -1. Follow it with Rule Engine node to add appropriate indication.

Select clause complex regex pattern

I am working on some application for my masters thesis and in the process I have to build a SQL Parser. To do so I've decide to go heavy on regexing since it seems the best way at the time.
The problem is that i have some minor problems with my regexes.
Considering some query examples such as:
select
RIC
from
(select
s.RIC, m.NAME
from
Stock s, Market m
where
s.LISTED_ON_EXCHANGE = m.RIC) t
where
RIC > 'G';
select *
from Stock
order by COMPANY
LIMIT 0,2;
select 1+2;
select now();
select
s.RIC, m.NAME
from
Stock s
INNER JOIN
Market ON m I s.LISTED_ON_EXCHANGE = m.RIC;
select *
from Stock
order by COMPANY;
select *
from Stock
where RIC in ('GS.N' , 'INFY.BO');
select *
from Stock
where RIC LIKE 'V%';
select *
from Stock
where RIC BETWEEN 'G' AND 'I';
select count(*)
from STOCK
where LISTED_ON_EXCHANGE IS NOT NULL;
select na_me as n, price as p
from bla, blabla, blalalaa;
And given the following two regexes:
SELECT_FIELDS_PATTERN = "(?<=[SELECT]) [\\d\\w',.*() ]+ (?=FROM)";
That should match selection fields.
And:
SELECT_FROM_PATTERN = "(?<=[FROM]) [\\w, ]+ (?(?=(?:WHERE|INNER|ORDER)))";
That should match FROM clauses excluding any conditions or ordering etc.
All of the queries except
select 1+2;
select now();
Should be valid. That's because I only want to parse select queries that contain relevant information for me.
The problem is that the two regexes I've created won't validate for example the last query:
select na_me as n, price as p from bla, blabla, blalalaa;
So I would require some help to improve my regexing for select queries, maybe even merge the two regexes?
An example of a correct output for the first query:
select RIC from (select s.RIC, m.NAME from Stock s, Market m where s.LISTED_ON_EXCHANGE=m.RIC) t where RIC > 'G';
The output should be:
RIC
for the first part and
(select s.RIC, m.NAME from Stock s, Market m where s.LISTED_ON_EXCHANGE=m.RIC) t
for the second part
Character classes are not groups -- remove [ & ] around keywords.
Don't use useless lookarounds, it can lead to problems in some cases.
You probably want to use \b around keywords so that SELECT does not match in FOOSELECT.
Can use (?i) to make the expression case insensitive.
You could use something like:
(?i)\bSELECT\b\s+(.+)\s+\bFROM\b\s+([\w\s,]+?)(?:\s+\b(?:WHERE|INNER|ORDER)\b|;?$)
With the parts of interest being captured in the first and second capturing group.
Note this will not work right with strings and in other cases, also SQL is recursive, which is pretty difficult to parse with Java regex. I suggest you use a proper parser if you want to parse SQL properly. (You can write a simple one your self, using regex for lexing generating tokens and Java to parse the tokens and build a parse tree.)

SQLite querying for exact matches

SQLite statement 'abc' LIKE 'ABCd' will return true. So my question is how to make an SQLite query that will return only exact record matches for a particular query.
The LIKE operator has two modes that can be set by a pragma. The default mode is for LIKE comparisons to be insensitive to differences of case for latin1 characters. Thus, by default, the following expression is true:
'a' LIKE 'A'
But if the case_sensitive_like pragma is enabled as follows:
PRAGMA case_sensitive_like=ON;
Then the LIKE operator pays attention to case and the example above would evaluate to false.
for exact record match you need to use = sign.
ex : abc = abc.
and if you want all records which contain abc words. You need to write
abc like '%abc%' in your sqllite query.

Fetching numbers from contacts using content resolver query - special case

I am trying to query phone number stored in the contacts database of android.
I am providing an input sting for comparison and I need the query to pick only those rows which matches this input string.
While querying the contacts db, I would like the query to ignore all the special characters contained in a number and compare the input string with only the digits contained in the field.
eg; if the stored number is (944) 6-129-337 , the query should compare the input string with 9446129337 and not with (944) 6-129-337 .
Following is the code with which I query the db and fetch the numbers.
contactCursor = getContentResolver().query(uri, projection,
ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "' AND " +
ContactsContract.CommonDataKinds.Phone.NUMBER + " LIKE ? ",new String[] { input_string }, null);
The problem I have here is, it just does a plain search in each phone number field without internally removing(using regexp or modifying the query?) the special characters.
I do not know how to do that cleaning up of special characters inside query. Any help in this regard which would help me resolve this query issue will be well appreciated
Thanks,
Anees
As a hack that may work for you... you could pass your number using wildcards between every digit, and then re-filter the results in your Java code... e.g. ... LIKE '%9%4%4%6%1%2%9%3%3%7%' ... is liable to return very few results, including (944) 6-129-337 and (perhaps) +1 (944) 612-9337; but you can collect these results, strip the non-digit values in your own code, and compare them. If you have very short search strings, though, your number of "false positive" hits will be much greater. Unfortunately, I haven't tested this with the Android content system, so it's plausible that you could overflow the number of wildcard characters permitted, or similar :-(
Use This
Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/%915894%");
Return Only your need.

Exact match with sql like and the bind

I have a bind in the SQL query
SELECT * FROM users WHERE name LIKE '%?%'
the bind set the ?.
Now, if i want to search with like method everything work but if, without change the sql, i want to search the exact match i dont now how to do.
I tried some regexp int the textbox es:
_jon \jon\ [jon] and some others but nothing work properly.
Any ideas?
Change your query to
select * from users where name like '?'
If you want to do a wildcard match, put the wildcards as part of the string that you're binding to the variable. If you don't want to do a wildcard match, then don't.
Note that like and = have the same performance except when your wildcard character is first in the string (for example, '%bob') as in that case the query optimizer can't use indexes as well to find the row(s) that you're looking for.
you can't search an exact match if the sql contains % symbols, as they are wildcards. you'll need to change the sql to
select * from users where name = '?'
for an exact match
(you can also use select * from users where name like '?' but that's more inefficient)
What is keeping you from changing the SQL?
The Like condition is for 'similar' matches, while the '=' is for exact matches.

Categories