I Have a string foo = "a,b". Now I want to search in the mysql database to get user_id while comparing the string to the likes field. The likes field has data in the format interest => a c v d b.
The different characters are seperated by a space. I tried Using like but the result was not upto the mark. How can I go about it?
This is my code
select user_id from users where interest like %foo%;
MySql does not support multiple keyword search in set like field, you should add OR condition of each search keyword with REGEXP
if your format interest like=> a,c,v,d,b then you can use FIND_IN_SET() function otherwise REGEXP provide to exact search.
SELECT user_id FROM users
WHERE interest REGEXP '[[:<:]]a[[:>:]]' AND interest REGEXP '[[:<:]]b[[:>:]]'
this query search only a and b in field not aa, bbax
LIKE does not support exact search.
Related
I try to use a regex with mysql that search boundary words in a json array string but I don't want the regex match words order because I don't know them.
So I started firstly to write my regex on regex101 (https://regex101.com/r/wNVyaZ/1) and then try to convert this one for mysql.
WHERE `Wish`.`services` REGEXP '^([^>].*[[:<:]]Hygiène[[:>:]])([^>].*[[:<:]]Radiothérapie[[:>:]]).+';
WHERE `Wish`.`services` REGEXP '^([^>].*[[:<:]]Hygiène[[:>:]])([^>].*[[:<:]]Andrologie[[:>:]]).+';
In the first query I get result, cause "Hygiène" is before "Radiothérapie" but in the second query "Andrologie" is before "Hygiène" and not after like it written in the query. The problem is that the query is generated automatically with a list of services that are choosen with no order importance and I want to match only boundary words if they exists no matter the order they have.
You can search for words in JSON like the following (I tested on MySQL 5.7):
select * from wish
where json_search(services, 'one', 'Hygiène') is not null
and json_search(services, 'one', 'Andrologie') is not null;
+------------------------------------------------------------+
| services |
+------------------------------------------------------------+
| ["Andrologie", "Angiologie", "Hygiène", "Radiothérapie"] |
+------------------------------------------------------------+
See https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html#function_json-search
If you can, use the JSON search queries (you need a MySQL with JSON support).
If it's advisable, consider changing the database structure and enter the various "words" as a related table. This would allow you much more powerful (and faster) queries.
JOIN has_service AS hh ON (hh.row_id = id)
JOIN services AS ss ON (hh.service_id = ss.id
AND ss.name IN ('Hygiène', 'Angiologie', ...)
Otherwise, in this context, consider that you're not really doing a regexp search, and you're doing a full table scan anyway (unless MySQL 8.0+ or PerconaDB 5.7+ (not sure) and an index on the full extent of the 'services' column), and several LIKE queries will actually cost you less:
WHERE (services LIKE '%"Hygiène"%'
OR services LIKE '%"Angiologie"%'
...)
or
IF(services LIKE '%"Hygiène"%', 1, 0)
+IF(services LIKE '%"Angiologie"%', 1, 0)
+ ... AS score
HAVING score > 0 -- or score=5 if you want only matches on all full five
ORDER BY score DESC;
id text_1 text_2
1 おはよう おはよ
2 こんにちは ちわー
3 大丈夫 さよなら
4 でんわしたい でんわしよう
I have DB same above.
I want to search with input: おはよう大丈夫?
Expect result will match: id = 1 and id = 3.
Please help me how to query search in Mysql? Thanks you.
The following SQL query will fetch your 2 ids for exact string matching
select id from TABLENAME where text_1 in ('おはよう','大丈夫');
You can also use like operator with % to fetch approximately strings id.
You might face encoding issue (文字化け)depending on your DB settings, so you might have to convert SJIS <-> UTF-8
https://dev.mysql.com/doc/refman/5.7/en/faqs-cjk.html#faq-cjk-what-cjk-avail
Last but not least, if you want to use the full string as a comparison criteria to select the rows, then you can reuse the following code:
how to compute similarity between two strings in MYSQL
select id from TABLENAME where text_1 REGEXP "おはよう大丈夫"
I have two fields in my MySQL database that are arrays. The datatype is shown as LONGTEXT with a Comment of (DC2Type:array).
For example, the integer values stored in this field would look like this:
a:4:{i:0;i:9;i:1;i:10;i:2;i:11;i:3;i:12;}
And the String values would look like this:
a:2:{i:0;s:6:"Value1";i:1;s:6:"Value2";}
I need these fields this way so I can store columns that are filterable. E.g. the first one may be age groups so ages 9,10,11,12 are represented.
My query must then get all records that say are relevant for age 10 or in some cases say I want to find those that are 10 and 11.
I've tried the IN and FIND_IN_SET syntaxes but neither is returning any results.
Using IN
SELECT *
FROM table_name
WHERE MyField IN (10)
Using FIND_IN_SET
SELECT *
FROM table_name
WHERE FIND_IN_SET(MyField,'Value1') > 0;
I know arrays are probably not the best field to store values in but I didn't want to have separate fields for each AgeGroup e.g. Age1, Age2, etc. or each category e.g Value1, Value2, etc.
Any thoughts on how I can find a value or values from a database array field, please?
Thanks!
You can use a pattern match.
Integer:
WHERE MyField LIKE '%i:10;%'
String:
WHERE MyField LIKE '%s:6:"Value1";%'
6 has to be replaced with the length of the string you're searching for.
If you want to search for multiple numbers or strings, you can use a regular expression with alternation:
WHERE MyField RLIKE 'i:(10|11);'
WHERE MyField RLIKE 's:(6:"Value1"|10:"LongValue2");'
Note that none of these methods can make use of an index on the table. It's generally a bad idea to store arrays in database columns, you should store them as separate rows in a many-to-many table.
I have a mysql query as follows.
$query="SELECT name,activity FROM appid
where result > 5 AND name LIKE :term ORDER BY name ASC LIMIT 0,40";
$result = $pdo->prepare($query);
$result->bindvalue(':term','%'.$_GET["q"].'%',PDO::PARAM_STR);
$result->execute();
What i want to do is this.
I have and entry like this that i want to find
'News & Weather'
However when i type
'news weather'
it of course will not find it. How can i be able to type that and retrieve that entry?
Regular expressions can do the trick:
select *
from appid
where name rlike 'news|weather' -- Matches 'news' or 'weather'
Another example:
select *
from appid
where name rlike 'news.*weather' -- Matches 'news' and 'wether'
-- with any characters in-between or none at all
-- (ordered)
Just one more:
select *
from appid
where name rlike '^news.{1,}weather$' -- Matches any text that starts with 'news'
-- and has at least one character before
-- ending with 'weather'
Regular espressions can be used to create very complicated filters on text fields. Read the link above for more information.
If you can add a full-text index to your table, Full-text search might be the better way to go with this. Specifically, a boolean Full-Text search:
select *
from appid
where match(name) against (+news +weather)
I believe the only way possible are through code:
Option A: Replace the spaces in your query parameter with '%' in code, but that of course will make the multiple words ordered
Option B: Split your parameter on spaces and dynamically construct your query with as many LIKEs as needed, adding additional ":termN" parameters for each one.
I'm going to search my database (SQL Server 2008) using a stored procedure. My users can enter keyword(s) in a textbox (keywords can be separated using , for instance).
Currently I'm using something like this:
keyword like N"%'+#SearchQuery%'%"
(keyword is a nvarchar column in my table, and #SearchQuery is the input to my stored procedure)
It works fine but what if user types several keywords: apple,orange, banana
Should I limit number of my keywords? How should I write my stored procedure if I have more than one keyword? How should I pass my user input to the stored procedure? I should pass apple, orange, banana as a whole phrase and then I should parse them in my stored procedure, or I should separate my keywords and send 3 keywords? How can I query these 3 keywords? A for loop?
What are best practices for performing such queries?
thanks
Do the parsing of the keywords in your application. SQL is not the best place for string manipulation.
Send the keywords as a table valued parameter (ie : http://www.mssqltips.com/sqlservertip/2112/table-value-parameters-in-sql-server-2008-and-net-c/ ) then you aren't limited to a fixed number of keywords.
Add the wildcards to the parameter in the stored procedure
update #keywords set keyword = '%'+keyword+'%'
filter your results by joining your source data to this table
eg:
SELECT result
FROM source
INNER JOIN #keywords keywords
ON source.keyword LIKE keywords.keyword
It depends on:
* How big it's your database.
* How often users will search for something.
* How precise results users except.
LIKE is not performance daemon, especially starting with %.
Maybe you should try full search text?
If you would like stay with LIKE (it will works only for small tables) I would try something like:
Split intput by , character (insert them into table as podiluska suggested is a good idea).
Build query for each token and UNION all results. Or run it in loop for each token and insert results to temporary table.
If you need some precise results (i.e. only records matches all 3 words) you can select most matching results from temporary results built above.
You could use CTE to split the string of keywords in a temporary table and then use it as you like. The keyword list can even have numbers or any characters, like %$<> or what you want, just remember comma is the string separator
DECLARE #CommaSeparatorString VARCHAR(MAX),
#CommaSeparatorXML XML
DECLARE #handle INT
SELECT #CommaSeparatorString = 'apple,orange,banana'
SELECT #CommaSeparatorString = REPLACE(REPLACE(#CommaSeparatorString,'<','$^%'),'>','%^$')
SELECT #CommaSeparatorXML = CAST('<ROOT><i>' + REPLACE(#CommaSeparatorString, ',', '</i><i>') + '</i></ROOT>' AS XML)
SELECT REPLACE(REPLACE(c.value('.', 'VARCHAR(100)'),'$^%','<'),'%^$','>') AS ID
FROM (SELECT #CommaSeparatorXML AS CommaXML) a
CROSS APPLY CommaXML.nodes('//i') x(c)
Result:
ID
------
apple
orange
banana