I have the following MySQL query which works
SELECT *,
CONCAT( office, ' ', contactperson ) AS bigDataField
FROM webcms_mod_references
HAVING bigDataField REGEXP "one|two"
Now there is no ORDER BY and if:
- bigDataField contains "one" this field is shown
- bigDataField contains "one two" this field is shown aswell
now it depends on the id which one of those is shown first, but I want the one with the more matches to be shown first!
I tried with
SUM(
CASE WHEN bigDataField REGEXP "one|two"
THEN 1
ELSE 0 END
) AS matches
But that does not work. Can anyone help me. I think the best would be as the title says to count the matching charachters from the REGEXP. If there are other ways please explain.
The REGEXP is a user input, so, I'm trying to implement a small search over a small Database.
This is theoretical whilst sqlfiddle is down but you might have to split the REGEXP into two so you can count the matches. REGEXP will return either a 0 or 1. Either it matched or didn't. There's no support for finding how many times it was matched in a string.
SELECT *,
CONCAT( office, ' ', contactperson ) AS bigDataField
FROM webcms_mod_references
HAVING bigDataField REGEXP "one|two"
ORDER BY (bigDataField REGEXP "one" + bigDataField REGEXP "two") DESC
There is no way to count the amount of matches on a regex. What you can do is match them separately and order by each of those matches. EG:
SELECT *,
CONCAT( office, ' ', contactperson ) AS bigDataField
FROM webcms_mod_references
HAVING bigDataField REGEXP "one|two"
ORDER BY
CASE WHEN bigDataField REGEXP "one" AND bigDataField REGEXP "two" THEN 0
ELSE 1 -- The else should catch the "two" alone or the "one" alone because of the filtering
END
Of course, you can use a LIKE here too but maybe your regex are more complex than that :)
When I want to count some substring I do replace and "-" the length, example:
SELECT (
LENGTH('longstringlongtextlongfile') -
LENGTH(REPLACE('longstringlongtextlongfile', 'long', ''))
) / LENGTH('long') AS `occurrences`
I think this is an elegant solution for a problem of counting how many times 'long' appears inside provided 'string'
This is not especially the answer to this question, but I think strongly attached to it... (And I hope, will help someone, who cames from google, etc)
So if you use PHP (if not, may dont keep reading ...), you can build the query with that, and in this case, you can do this (about #Moob great answer):
function buildSearchOrderBy(string $regex, string $columName, string $alternateOrderByColumName): string
{
$keywords = explode ('|', $regex);
if (empty ($keywords)) {
return $alternateOrderByColumName;
}
$orderBy = '(';
$i = 0;
foreach ($keywords as $keyword) {
$i++;
if ($i > 1) $orderBy .= " + ";
$orderBy .= "IF((" . $columName . " REGEXP '" . $keyword . "')>0, " . (100 + strlen($keyword)) . ", 0)";
}
$orderBy .= ')';
return $orderBy;
}
So in this case every match worth 100 + so many scores, what the numbers of the characters in the current keyword. Every match starting from 100, because this ensure the base, that the first results will be these, where the total score originate from the more matches, but in proportionally worth more a longer keyword in any case.
Builded to one column check, but I think you can update easy.
If copied to your project, just use like this (just an example):
$orderBy = buildSearchOrderBy($regex, 'article.title', 'article.created');
$statement = "SELECT *
FROM article
WHERE article.title REGEXP '(" . $regex . ")'
ORDER BY " . $orderBy . " DESC"
;
Related
I have a column in MySQL in the following format after I run a certain $sql:
colname
12
15
10
23
12
2
What I want is to transfer this into
$colname = array(12,15,10,23,12,2)
I came up with:
$results = $wpdb->get_results($sql);
$colname=array();
foreach($results as $result){
$colname[] = $result;}
Is this the most efficient way? The order is also very important
You can probably use something like:
$sql =
"SELECT " .
" group_concat(colname ORDER BY order_by SEPARATOR ',') AS txt_result " .
"FROM " .
" t ; " ;
$results = $wpdb->get_results($sql);
$colname = split(',', $results[0]['txt_result'])
Note that you need a certain ORDER BY expression. By default, SQL does not provide any determined order. $colname will be an array of textual representations of your numbers. You should convert them to numbers if need to.
See the result of the SQL query at dbfiddle here
Reference:
GROUP_CONCAT()
I have a table with fullname column. I want to make a query for finding a person via his last name but his last name is in the full name column.
Would it matter if it accidentally returned someone whose first name matched your query?
A simple query would be:
SELECT *
FROM TABLE
WHERE fullname LIKE '%insertlastname%'
If you want to define the last name as the name after the last space:
SELECT substring_index(fullname, ' ', -1) as lastname
FROM TABLE
WHERE lastname='insertlastname'
Two suboptimal answers, but some answers at least.
enter code here You can use this if you want to fetch by query:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX( `fullname` , ' ', 2 ),' ',1) AS b,
SUBSTRING_INDEX(SUBSTRING_INDEX( `fullname` , ' ', -1 ),' ',2) AS c FROM `users` WHERE `userid`='1'
But you can also try by PHP to fetch last name. You just use explode function to fetch last name.
Exm:
$full_name = "row moin";
$pieces = explode(" ", $fullname);
echo $first_name = $pieces[0]; // row
echo $last_name = $pieces[1]; // moin
A simple answer for this is like this suppose we have a name
Charles Dickens
:
SELECT * FROM TABLE_NAME WHERE SUBSTRING_INDEX(FULLNAME,' ',-1) like '%Dickens';
I wanted to add 3 periods to a result string if the string is over 20 characters. The result is using Group_Concat which works fine, I just don't know the best way to modify the result if over 20 chars.
query
LEFT(GROUP_CONCAT(employee.firstname, ' ', employee.lastname), 20) as employeenames
Totally untested:
CASE
WHEN CHAR_LENGTH(GROUP_CONCAT(employee.firstname, ' ', employee.lastname))>20
THEN CONCAT(LEFT(GROUP_CONCAT(employee.firstname, ' ', employee.lastname), 20) '...')
ELSE GROUP_CONCAT(employee.firstname, ' ', employee.lastname)
END AS employeenames
It's not likely that this performs decently, though. This is the kind of stuff your client-side language will possibly do way better.
In my db I have phone numbers like 094-144-54
But I have to find them only with 09414454
Right now I've got this:
0[^[:digit:]]*9[^[:digit:]]*4[^[:digit:]]*1[^[:digit:]]*4[^[:digit:]]*4[^[:digit:]]*5[^[:digit:]]*4
It works, but is there a shorter way to write this? I know \D but I think it doesn't work with the MySQL RegtExp implementation.
Also, how do I select several rows like this?
SELECT number FROM tb1 WHERE ((number REGEXP ' ... '), (number REGEXP ' ... '), ... );
This doesn't work.
I tested this a pure digit number starting with 0 and ended by 4:
SELECT number FROM tb1 WHERE (number REGEXP '^0[[:digit:]]*4$');
Or a pure digit number as this:
SELECT number FROM tb1 WHERE (number REGEXP '^[[:digit:]]+$');
This php to reform an input string "09414454":
<?php
$strPhoneNo = "09414454";
$strPhoneNo = substr(chunk_split($strPhoneNo, 3, '\-'), 0, -2);
//
// => "094\-144\-54"
//
$strSQL = "SELECT number FROM tb1 WHERE (number REGEXP '^$strPhoneNo$');";
//
echo "<pre>\n";
echo $strSQL;
echo "</pre>\n";
//
// $strSQL:
// SELECT number FROM tb1 WHERE (number REGEXP '^094\-144\-54$');
//...
?>
How to change when the value is 0 then '-' in my sql especially the field have value percentage.
Anyone know about this?
Try the following Query:
select
CASE (column name) WHEN '0' THEN '-' ELSE (column name) END
from (table name)
you can use IF
select IF(Myfield = 0 , '-', Myfeild) from table
try this query ::
SELECT replace('980','0','-') from dual;
output:
REPLACE('980','0','-')
98-
REPLACE function is used to replace the desired characters from a string
try this, this will find and replace the value
update [table_name]
set [field_name] = replace([field_name],'0','-');
This statement will replace 0 to -, and display number as text with percent otherwise:
SELECT
CASE mycol WHEN 0
THEN '-'
ELSE concat(mycol, '%')
END AS pct
FROM mytable
Arguably, this is better done on client side, but I leave it to another answer.
Try this
<?php
$query = "Select * from 0 in";
$result = str_replace('0', '-', $query);
echo $result;
?>