php and regex: search for word in string - php

How can i found word in string using regex or not in this string
String is Mysql Query
SELECT
id,
name,
desc,
(SELECT id as lid FROM comments WHERE lid = id order by id desc limit 1) as lid_com
FROM posts limit 3
here i want to search for limit in the last of string
string may be
limit 3
limit 3, 3
limit 3 , 3
limit 3 ,3
3 here may be any number
i tried this regex but i'm beginner
"/ limit [0-9]{0,9}+\,[0-9]{0,9} /i$"
how can i do this
Thank you

$string = 'SELECT
id,
name,
desc,
(SELECT id as lid FROM comments WHERE lid = id order by id desc limit 1) as lid_com
FROM posts limit 3 ,3';
echo preg_match('/(limit)\s\d(((\,\s)|(\s\,\s)|(\s\,))\d)?$/i', $string, $matches); //1
print_r($matches); //$matches['0'] == 'limit 3 ,3'

"/limit[\s]+[\d]+[\s]*,[\s]*[\d]+$/i"
This searches case insesitive for:
"limit"
one or more whitespaces
one or more digits
zero or more whitespaces
a comma
zero or more whitespaces
one or more digits
at the end of the string

Do not remember, whether LIMIT is always a last SQL statement, so I'd use
/limit\s+(\d+)(?:\s*,\s*(\d+))?(?=[^\n]+\Z)/mi

Try this condition -
SELECT * FROM table WHERE column
REGEXP '(^limit[[:space:]]+[[:digit:]]+[[:space:]]*,[[:space:]]*[[:digit:]]+$)|(^limit[[:space:]]+[[:digit:]]+[[:space:]]*$)';
The first part find strings like 'limit 3,3' -
^limit[[:space:]]+[[:digit:]]+[[:space:]]*,[[:space:]]*[[:digit:]]+$
The second one finds strings like 'limit 3' -
^limit[[:space:]]+[[:digit:]]+[[:space:]]*$

Related

How to order non-integer records in MySql?

I'm trying to order some MySQL records by DESC order and get the last record added.
These are my records and they're all stored as strings:
1/2017
1/2018
2/2017
2/2018
3/2017
I want to get the value 1/2018. The records are based on the current year
and the last record added was 1/2018 and the next will be 2/2018 and so on.
this is my query:
SELECT NoControl FROM cita ORDER BY NoControl DESC LIMIT 1
but I'm getting 3/2017 as the last record.
If you have ever the same pattern m/yyyy you could use some string manipulation function eg:
SELECT NoControl
FROM cita
ORDER BY right(NoControl,4), DESC left(NoControl,1) DESC LIMIT 1
But you should avoid of store date values as string ..
or convert the string as a proper date
SELECT NoControl
FROM cita
ORDER BY str_to_date(NoControl,'%m/%Y') DESC LIMIT 1
Use SUBSTRING_INDEX to extract the first and second part, CAST as integer and sort:
SELECT str
FROM testdata
ORDER BY
CAST(SUBSTRING_INDEX(str, '/', -1) AS UNSIGNED) DESC,
CAST(SUBSTRING_INDEX(str, '/', 1) AS UNSIGNED) DESC
LIMIT 0, 1
SQL Fiddle

MySQL Similar 2 Columns need begining data by 1st column

$genre = 'Action|Adventure|Crime';
$starcast= 'Tom Hanks|Felicity Jones|Omar Sy|Irrfan Khan';
$S2 = mysql_query("SELECT title,hash,year FROM IMDB WHERE starcast REGEXP '".$starcast."' or genre REGEXP '".$genre."' LIMIT 16") or die (mysql_error());
while ($S = mysql_fetch_assoc($S2)){
this is working but results are in mixed data.
data LIMIT is 16.
i want 1st all data by starcast.
Example :- If startcast data match with 9 result so last 7 data needed match with genre.
sorry for bad English.
Question is UPDATE.....
I doubt how your posted query works. It should throw compilation error. Your query should look like
SELECT title,hash,year
FROM IMDB WHERE starcast REGEXP '".$starcast."' or genre REGEXP '".$genre."'
ORDER BY id DESC
LIMIT 16
If startcast data match with 9 result so last 7 data needed match with genre
don't think you can make it like that unless you use UNION query like
(SELECT title,hash,year
FROM IMDB WHERE starcast REGEXP '".$starcast."'
ORDER BY id DESC LIMIT 9)
UNION
(SELECT title,hash,year
FROM IMDB WHERE genre REGEXP '".$genre."'
ORDER BY id DESC LIMIT 7 )

MySQL sort by number of occurrences

I am doing a search in two text fields called Subject and Text for a specific keyword. To do this I use the LIKE statement. I have encountered a problem when trying to sort the results by the number of occurrences.
my search query looks like this:
SELECT * FROM Table WHERE (Text LIKE '%Keyword%' OR Subject LIKE '%Keyword%')
I tried to add a count() statement and sort it by the number of occurrences, but the count() statement just keep returning the number of rows in my table.
Here is the query with count statement:
SELECT *, COUNT(Text LIKE '%Keyword%') AS cnt FROM News WHERE (Text LIKE '%Keyword%' OR Subject LIKE '%Keyword%') ORDER BY cnt
What im looking for is something that returns the number of matches on the Subject and Text columns on each row, and then order the result after the highest amount of occurrences of the keyword on each row.
Below query can give you the no.of occurrences of string appears in both columns i.e text and subject and will sort results by the criteria but this will not be a good solution performance wise its better to sort the results in your application code level
SELECT *,
(LENGTH(`Text`) - LENGTH(REPLACE(`Text`, 'Keyword', ''))) / LENGTH('Keyword')
+
(LENGTH(`Subject`) - LENGTH(REPLACE(`Subject`, 'Keyword', ''))) / LENGTH('Keyword') `occurences`
FROM
`Table`
WHERE (Text LIKE '%Keyword%' OR Subject LIKE '%Keyword%')
ORDER BY `occurences` DESC
Fiddle Demo
Suggested by #lserni a more cleaner way of calculation of occurrences
SELECT *,
(LENGTH(`Text`) - LENGTH(REPLACE(`Text`, 'test', ''))) / LENGTH('test') `appears_in_text`,
(LENGTH(`Subject`) - LENGTH(REPLACE(`Subject`, 'test', ''))) / LENGTH('test') `appears_in_subject`,
(LENGTH(CONCAT(`Text`,' ',`Subject`)) - LENGTH(REPLACE(CONCAT(`Text`,' ',`Subject`), 'test', ''))) / LENGTH('test') `occurences`
FROM
`Table1`
WHERE (TEXT LIKE '%test%' OR SUBJECT LIKE '%test%')
ORDER BY `occurences` DESC
Fiddle Demo 2
You want SUM instead. Count will count how many records have non-null values, which means ALL matches and NON-matches will be counted.
SELECT *, SUM(Text LIKE '%Keyword') AS total_matches
...
ORDER BY total_matches
SUM() will count up how many boolean true results the LIKE produces, which will be typecast to integers, so you get a result like 1+1+1+0+1 = 4, instead of the 5 non-nulls count.
// escape $keyword for mysql
$keyword = strtolower('Keyword');
// now build the query
$query = <<<SQL
SELECT *,
((LENGTH(`Subject`) - LENGTH(REPLACE(LOWER(`Subject`), '{$keyword}', ''))) / LENGTH('{$keyword}')) AS `CountInSubject`,
((LENGTH(`Text`) - LENGTH(REPLACE(LOWER(`Text`), '{$keyword}', ''))) / LENGTH('{$keyword}')) AS `CountInText`
FROM `News`
WHERE (`Text` LIKE '%{$keyword}%' OR `Subject` LIKE '%{$keyword}%')
ORDER BY (`CountInSubject` + `CountInText`) DESC;
SQL;
Returns number of occurrences in each field and sorts by that.
The 'keyword' needs to be lower cased for this to work. I don't think it's really fast, performance wise as it needs to lower-case fields and there's no case-insensitive search in MySQL afaik.
You could index each news item (subject and text) by words and store in another table with news_id and occurrence count and then match against that.

mysql search by title in last 100 records

My case is, when someone is posting to my news web data with 600k records,
they can create the same title which someone just posted in the last few hours with same subject.
data: sid|title|desc|timestamp|userid
Usually I use:
select sid from ".$prefix."_stories WHERE title = '".$subject."' limit 0,1
It searches all data for $subject then notice poster if have they have the same title.
I need a query which searches in the last 100 records.
I tried the following, but this did not work:
select sid from ".$prefix."_stories WHERE title = '".$subject."' and sid > MAX(sid)-100 limit 0,1
You can do this with a subquery that returns the last 100 sid. Note, I have omitted the PHP concatenations for brevity here.
SELECT
last100.sid
FROM
(
SELECT
sid,
title
FROM $prefix._stories
ORDER BY sid DESC LIMIT 100
) last100
WHERE
last100.title = '$subject'
Assuming that you have a primary key, incrementing by 1 with every record (which will put newest at the bottom), just do this:
SELECT sid, title
FROM ".$prefix."_stories
ORDER BY sid DESC
LIMIT 100
This will select the last 100 records
Good point by Michael in my comments... Edit to code and further comment:
Removing the where clause, this will select the last 100 records... Run a loop to check to see if the title or summary already exists:
while ($row = $result) {
if $subject = $row['title'] {
$duplicate = TRUE;
endwhile;
}
}
Just compare the resulting data. Thanks Michael
Sort by sid (descending, so newest entries come first) and limit results to 100:
$sql = "select t.sid from (select sid, title from ".$prefix."_stories ORDER BY sid DESC LIMIT 0,100) t WHERE title = '".$subject."';"
Be sure to chek $subject to avoid SQL Injection (better: Use prepared statements / PDO).

mysql: order by match

for looking up matching keywords in mysql i use
SELECT * FROM `test` WHERE `keywords` REGEXP '.*(word1|word2|word3).*' LIMIT 1
I want to order them by the most matching keywords in the keywords column to give the best answer.For example
Keywords /////////////// Response
word1,word2 /////////// test1
word1,word2,word3 / test2
I want the response to be test2 with the query given.
How can i order the results my the most matching keywords?
SELECT
(keywords REGEXP '.*(word1).*')
+(keywords REGEXP '.*(word2).*')
+(keywords REGEXP '.*(word3).*') as number_of_matches
,keywords
,field1
,field2
FROM test
WHERE keywords REGEXP '.*(word1|word2|word3).*'
ORDER BY number_of_matches DESC
LIMIT 20 OFFSET 0

Categories