Extract a search string in context - mysql

I'm trying to do a MySQL query where I extract the search string in context. So if the search is "mysql" I'd like to return something like this from the 'body' column
"It only takes minutes from downloading the MySQL Installer to having a ready to use"
This is what I've got now but it doesn't work because it just grabs the first 20 characters from the body field. While I'd like it to grab 20 chars in front of and behind the searched term so that the user can see what there term looks like in context:
SELECT id, title, substring(body, 0, 20) FROM content WHERE body LIKE '%mysql%' OR title LIKE '%mysql%';
Thanks

Here's the SQL you need:
SELECT
id,
title,
substring(body,
case
when locate('mysql', lower(body)) <= 20 then 1
else locate('mysql', lower(body)) - 20
end,
case
when locate('mysql', lower(body)) + 20 > length(body) then length(body)
else locate('mysql', lower(body)) + 20
end)
FROM content
WHERE lower(body) LIKE '%mysql%'
OR title LIKE '%mysql%'
limit 8;
FYI: Tested and works.

You could just pull the whole body value out and just extract the string in your code. If you're using php, you could do something like this, given you've already queried the body string and stored it in a var $body
$index = strpos($body, $searchStr);
$context = substr($body, $index-20, strlen($searchStr)+40);

Related

filter string only contains q in mysql

I need help in mysql query, i written this query
select * from post where content REGEXP '^q'
this query is working but it also includes spaces in filter, what i want to do if any content string like "qqqqqq" or "qqqq" or "qqq" or "qq" or "q" for this string only it should have to filter, right now what is happening if i have string like "qqqq qq" then also it is giving me the result, it should not consider that space, can anyone please help me to resolve this issue ?
You can fix your regexp like next:
select * from post where content REGEXP '^q+$';
This regular expression mean the string starts with q and contain only 1 or more q symbols till end of string
Test it on SQLize.online
Try Using this ^q+(?![\s])+$ Regular Expression.
Above RegExp will check for string starting with q and without space.
You don't really need a regex for this. String functions are likely to be more efficient. You can replace all "q"s with empty strings, and ensure that that resulting string is empty:
select * from post where replace(content, 'q', '') = ''
Note that this also allows the empty string. If you want to avoid that, then:
select * from post where content <> '' and replace(content, 'q', '') = ''

How to combine like and between in same statement (laravel Query Builder/model)

Following are the HDD column from the Computer model (I know it's not a good format to store data but it's already stored like that)
HDD
4x2TBSATA2
2x2TBSATA2
8x2TBSATA2
4x1TBSATA2
2x120GBSSD
4x480GBSSD
I want to fetch the range out of HDD column where storage is in a specific range, for example, fetch storage between 120GB to 1TB should output
4x1TBSATA2
2x120GBSSD
4x480GBSSD
I was wondering if it's possible to combine like and between in the same statement?
I tried the following which doesn't work.
select * from `server_details` where `HDD` between '%120GB%' and '%10TB%'
select * from `server_details` where `HDD` between "Like '%120GB%'" and "LIKE '%10TB%'"
If you need to do just in SQL, extract the size part, convert it to a number, and compare.
select *,
cast(`HDD` as unsigned)*
cast(substr(`HDD`,LOCATE('x',`HDD`)+1) as unsigned)*
(case when`HDD` LIKE '%TB%' then 1000 else 1 end) as GB
from `server_details`
where
cast(`HDD` as unsigned)*
cast(substr(`HDD`,LOCATE('x',`HDD`)+1) as unsigned)*
(case when`HDD` LIKE '%TB%' then 1000 else 1 end)
between 120 and 10000;
You can't use between with wildcard queries. You might be able to write a regular expression to match what you need, for example:
select * from `server_details` where `HDD` regexp '1[2-9]\dGB|[2-9]\d\dGB|\dTB|10TB'
but as you can see this is a very specific expression based on what you've written and each different limit will need a different expression.
There's some python code to generate such an expression but no PHP code that I could find (with some very basic googling)
Another solution (and what I would personally recommend) is to add the capacity as a separate column:
Migrate your current table:
class AddCapacityColumnMigration extends Migration {
public function up()
{
Schema::table('computers', function (Blueprint $table) {
$table->bigInt('capacityMB')->nullable();
});
Computer::chunk(100, function ($computers) {
foreach ($computers as $computer) {
if (preg_match('/(\d+)x(\d+)(M|G|T)B/',$computer->HDD,$m) {
$capacity = $m[1];
$capacity *= $m[3] === 'M' ? 1 : ($m[3] === 'G' ? 1000 : 1000000 );
$computer->capacityMB = $capacity * $m[2];
$computer->save();
}
}
});
}
Then you might want to add a creating and updating event in your model to ensure you always set the new capacityMB column. When all this is done your query is as simple as:
select * from `server_details` where `capacityMB` between 120000 and 10000000
In the database, in HDD column, you should not store alpha-numeric values like 120GB, 10TB, you should store numeric values like 120, 10000. Please try with the following query.
$hdds = DB::table('server_details')
->whereBetween('HDD', [120, 10000])
->get();

Get content from another DB in wordpress

I have found out how to make a page for WordPress, where I can write PHP code into.
However, I can not figure out how to retrieve content from another database.
I have found the connect code:
$wpdb2 = new wpdb($dbname, $dbpass, $dbuname, $dbhost);
but I cannot figure out how to retrieve content from the database.
Can someone give an example?
If, for example, have this query
SELECT number
FROM qr_statistic
WHERE date = '$today'
please see this:
wpdb::get_results( string $query = null, string $output = OBJECT )
now you can write your query:
$result = $wpdb->get_results("SELECT number FROM $wpdb->qr_statistic WHERE WHERE date = '$today'");
also see this link

mysql search for brackets

To classifie the movies of some friends, i did create a mysql table. we decided to Name the movies as example "dirty.fingers.(2006)". somehow i cant find this title when i search for "title LIKE dirty.fingers.(2006) as the brackets are disturbing. i did split the search like "title REGEXP dirty.fingers AND tilte REGEXP 2006". now it did fail once i did try to add the movie fingers out of the year 2006; the db found it as dublicate.
is there a way to search a text with brackets. i Need to search with LIKE
i did try with fingers.\(2006\), also with fingers.?2006?... no success
in other words... at the moment i use
select * from filme where Pfad_M REGEXP '$parttitle' AND Pfad_M REGEXP '$year'
as
select * from filme where Pfad_M LIKE '$title'
is not working.
variables value are as example:
$title = 'dirty.fingers.(2006)'
$parttitle = 'dirty.fingers'
$year = '2006'

Strip special characters and space of a DB column to compare in rails

I have 4 types of last_name:
"Camp Bell"
"CAMPBELL"
"CampBellJr."
"camp bell jr."
Now, in rails when an user is searched by it's last name like camp bell, I want to show all the 4 records. So, I tried:
RAILS
stripped_name = params[last_name].gsub(/\W/, '')
#=> "campbell"
User.where("LOWER(REPLACE(last_name, '/\W/', '')) LIKE ?", "#{stripped_name}%")
Give me only 2 records with following last_name:
"CAMPBELL"
"CampBellJr."
I guess, this is because, the mysql REPLACE is not working correctly with regex.
Any ideas?
EDIT
Guys, sorry for the confusion. My idea is to strip off all special characters including space. So I'm trying to use \W regex.
For example, the input can be: camp~bell... But, it should still fetch result.
You can check for both stripped_name without space and ones that include both names seperated with space like this.
stripped_name = params[last_name].gsub(/\W/, '')
split_names = params[last_name].split(" ")
User.where('name LIKE ? OR (name LIKE ? AND name LIKE ?)', "%#{stripped_name}%", "%#{split_names[0]}%", "%#{split_names[1]}%")
Next step would to search for complete array of split names not just first two.
Here my solution:
User.where("REPLACE(last_name, ' ', '') ILIKE CONCAT ('%', REPLACE('?', ' ', ''),'%')", stripped_name)
ILIKE is like LIKE but the I is for insensitive case.
To understand easily step by step:
lastname ILIKE '%campbell% you need % because you want lastname
contain this string, not necessary at the begin or the end of you
string.
'campbell%' => search string who begin by campbell
'%campbell' => search string who finish by campbell
We need generate '%campbell%, so we use CONCAT for that
I just use a simply REPLACE, but maybe you should use a regex.