search the inbetween string using sql query - mysql

In wp_postmeta table meta_value contains the value http/google.co.in/
If the user searches for http/google.co.in/testing, then the resultset should contain http/google.co.in/
I tried with following query:
SELECT * FROM wp_postmeta WHERE meta_value LIKE '%http/google.co.in/testing%'
but it did not return the expected result.
How can i get the desired result? How can I use regular expressions to get this result?

if you use sql: .....LIKE '%http/google.co.in/testing%', then DB will look for any string containing "http/google.co.in/testing". Note that your desired result does not contain "testing" inside.
Let's try:
SELECT * FROM wp_postmeta WHERE meta_value LIKE CONCAT('%', SUBSTR('http/google.co.in/testing', 1, 18), '%')

this '%http/google.co.in/testing%' means you are looking for any string that contains 'http/google.co.in/testing' so 'http/google.co.in/' won't return any result because it doesn't contain the string you are looking for.
You can use SUBSTR() to search for a part your string.

As others have pointed out, LIKE searches for strings containing the entire search string (plus any other strings where the %s are), not strings containing a substring of your string. I don't know if there is such a command.
You suggested perhaps regex is your answer. MySQL does in fact have a regex command, which a quick Google search would show you the documentation for here: http://dev.mysql.com/doc/refman/5.7/en/regexp.html
Do you need further help determining your regex, or is this enough?
If you want further help, you'll have to clarify exactly what regex would be searching for, because you'd have to understand the components of your search string to know what will be constant and what will be variable.

Related

SQL replace all specified keys

I have one column(varchar) containing only json string within one table. I want replace all keys with "" on that column. How can I do that using sql? My database is MySQL.
For example:
|--------------------------------------------------------------------|
| t_column |
|--------------------------------------------------------------------|
| {"name":"mike","email":"xxx#example.com","isManage":false,"age":22}|
|--------------------------------------------------------------------|
SELECT replace(t_column, regexp, "") FROM t_table
I expect:
mikexxx#example.comfalse22
How to write that regexp?
Start from
select t_column->'$.*' from test
This will return a JSON array of attribute values:
[22, "mike", "xxx#example.com", false]
This might be already all you need, and you can try something like
select *
from test
where t_column->'$.*' like '%mike%';
Unfortunately there seems to be no native way to join array values to a single string like JSON_ARRAY_CONCAT(). In MySQL 8.0 you can try REGEXP_REPLACE() and strip all JSON characters:
select regexp_replace(t_column->'$.*', '[" ,\\[\\]]', '') from test
which will return '22mikexxx#example.comfalse'.
If the values can contain one of those characters, they will also be removed.
Note: That isn't very reliable. But it's all I can do in a "simple" way.
See demo on db-fiddle.
I could be making it too simplistic, but this is just a mockup based on your comment. I can formalize it into a query if it fits your requirement.
Let's say you get your JSON string to this format where you replace all the double quotes and curly brackets and then add a comma at the end. After playing with replace and concat_ws, you are now left with:
name:mike,email:xxx#example.com,isManage:false,age:22,
With this format, every value is now preceded by a semicolon and followed by a comma, which is not true for the key. Let's say you now want to see if this JSON string has the value "mike" in it. This, you could achieve using
select * from your_table where json_col like '%:mike,%';
If you really want to solve the problem with your approach then the question becomes
What is the regex that selects all the undesired text from the string {"name":"mike","email":"xxx#example.com","isManage":false,"age":22} ?
Then the answer would be: {\"name\":\"|\"email\":\"|\",\"isManage\":|,\"age\":|}
But as others let you notice I would actually approach the problem parsing JSONs. Look up for functions json_value and json_query
Hope I helped
PS: Keep close attention on how I structured the bolded sentence. Any difference changes the problem.
EDIT:
If you want a more generic expression, something like select all the text that is not a value on a json-formatted string, you can use this one:
{|",|"\w+\":|"|,|}

MySQL full text search on JSON data

I'm trying to replicate the following LIKE query using a full text search on JSON data;
SELECT * FROM table
WHERE response LIKE '%"prod_id": "foo"%'
AND response LIKE '%"start_date": "2016-07-13"%'
In my database the above query returns 28 rows
This is my attempt:
SELECT * FROM table
WHERE MATCH(response)
AGAINST('+"\"prod_id\": \"foo\"",+"\"start_date\": \"2016-07-13\""')
However this returns over 4,500 rows (the same as running the first query for only the prod_id ~1,900 rows when running the first query on just the date)
It was my understanding that +"text here" would indicate a required word, and that literal double quotes (present in the JSON data) should be escaped, and that , would indicate a split between the two strings I'm looking for. What am I not understanding correctly? Is there any point in running this as a full text query anyway?
Thanks to #Sevle I've tweaked my query like so, and it's returning the correct results;
SELECT * FROM table
WHERE MATCH(response)
AGAINST('+\"prod_id: foo\" +\"start_date: 2016-07-13\"' IN BOOLEAN MODE)
The comma was not helping and I was escaping the wrong characters, and of course I did need IN BOOLEAN MODE to be added. Finally, I removed the double quotes I was searching for in the JSON string.
It may also be worth noting that as I'm using PHP PDO to run this query I also had to make the following tweaks.
Instead of constructing the query like so trying to bind the variables like I normally would;
$query = $db->prepare('...AGAINST('+\"prod_id: :prod_id\" +\"start_date: :start_date\"');
$query->execute(array('prod_id' => 'foo', 'start_date' => '2016-07-13'));
I had to do this, as I found I could not bind variables in full text searches
$sql_against = $db->quote('...AGAINST('+\"prod_id: foo\" +\"start_date: 2016-07-13\"');
$query = $db->prepare("...AGAINST($sql_against IN BOOLEAN MODE)")

Mysql 'match against' with multiple criteria

How to compare records from one column with 'match against'? That code is not working properly:
$sql = 'SELECT * FROM `database` WHERE MATCH (`content` WHERE `id` != \'\')AGAINST (`content` WHERE `id` = \'\' IN BOOLEAN MODE)';
$p = $db->query($sql);
As documented, the MATCH() syntax is like this:
MATCH (col1,col2,...) AGAINST (expr [search_modifier])
And is described as:
MATCH() takes a comma-separated list that names the columns to be searched. AGAINST takes a string to search for, and an optional modifier that indicates what type of search to perform. The search string must be a string value that is constant during query evaluation. This rules out, for example, a table column because that can differ for each row.
So, the syntax you have used is completely invalid.
I'm not sure of what you're asking for. Someone else has provided a pretty good response to a similar question posted in the following link:
Mysql search for string and number using MATCH() AGAINST()
Again it seems to me that you are trying to match patterns/expressions between 2 columns from 2 different tables, if I have understood your example correctly. If so, then maybe the solution provided in the link isn't 'the way to go'. It's up to you, hope it helps..

Using MySQL LIKE operator for fields encoded in JSON

I've been trying to get a table row with this query:
SELECT * FROM `table` WHERE `field` LIKE "%\u0435\u0442\u043e\u0442%"
Field itself:
Field
--------------------------------------------------------------------
\u0435\u0442\u043e\u0442 \u0442\u0435\u043a\u0441\u0442 \u043d\u0430
Although I can't seem to get it working properly.
I've already tried experimenting with the backslash character:
LIKE "%\\u0435\\u0442\\u043e\\u0442%"
LIKE "%\\\\u0435\\\\u0442\\\\u043e\\\\u0442%"
But none of them seems to work, as well.
I'd appreciate if someone could give a hint as to what I'm doing wrong.
Thanks in advance!
EDIT
Problem solved.
Solution: even after correcting the syntax of the query, it didn't return any results. After making the field BINARY the query started working.
As documented under String Comparison Functions:
Note
Because MySQL uses C escape syntax in strings (for example, “\n” to represent a newline character), you must double any “\” that you use in LIKE strings. For example, to search for “\n”, specify it as “\\n”. To search for “\”, specify it as “\\\\”; this is because the backslashes are stripped once by the parser and again when the pattern match is made, leaving a single backslash to be matched against.
Therefore:
SELECT * FROM `table` WHERE `field` LIKE '%\\\\u0435\\\\u0442\\\\u043e\\\\u0442%'
See it on sqlfiddle.
it can be useful for those who use PHP, and it works for me
$where[] = 'organizer_info LIKE(CONCAT("%", :organizer, "%"))';
$bind['organizer'] = str_replace('"', '', quotemeta(json_encode($orgNameString)));

PHP/MYSQL match against query

I am trying to run a match against query and it is not working. I created a full text index on the two fields. But am getting sql error right before word 'relationship". Here is sql:
"SELECT * FROM pages WHERE MATCH (shdescript,ldescript) AGAINST (romance, relationship)";
I have also tried just searching against shdescript and just searching against ldescript but get same error. Also I've tried searchstring without spaces. As far as I know, you are supposed to have the words of the searchstring separated by commas in parentheses. What am I doing wrong? Thanks.
Add quotes around your search string.
"SELECT * FROM pages WHERE MATCH (shdescript,ldescript) AGAINST ('romance', 'relationship')";
Also make sure you protect yourself against the nasty SQL injection threat, read more here.
Try quoting your string (i.e 'romance' and 'relationship')
SELECT * FROM pages WHERE MATCH (shdescript,ldescript) AGAINST ('romance', 'relationship')
I believe your AGAINST must be in quotes. From:
http://dev.mysql.com/doc/refman/4.1/en/fulltext-search.html#function_match
AGAINST takes a string to search for, and an optional modifier that
indicates what type of search to perform. The search string must be a
literal string, not a variable or a column name.