How to find the column values present in a given sentence? mysql - php

Consider the following mysql table
id name
----- ------
1 Mark
2 Mike
3 Paul
4 John
And consider the input sentence
Mark and Paul are very good friends since 2000.
Expected output
Mark , Paul
I want to find the names present in the input sentence.
Does mysql provides any options to find this. Or any ideas?

This can be achieved two way. Using 'IN' and 'REGEX' operator of mysql.
By using 'IN' Operator
<?php
$string = "Mark and Paul are very good friends since 2000.";
$sql_in = "'".implode("','",explode(" ",$string))."'";
//Will return all the records for which name match with any word in given sentence.
$mysql_query = "select * from table_name where name in($sql_in)";
?>
By using 'REGEX'
<?php
$string = "Mark and Paul are very good friends since 2000.";
$regex_string = str_replace(' ','|',$string);
//Will return all the records for which name match with any word in given sentence.
$mysql_query = "select * from table_name where name REGEX '^(".$regex_string.")'";
?>

I don't know that mysql have some options for that. But you can split the string and search for the names.
$sentence = "Mark and Paul are very good friends since 2000."
//some code to get all names from the database
//simulation mysql-output as array
$names = array("Mark", "Mike", "Paul", "John");
//first split the String into a array what contains all words of the sentences
$array = explode(" ", $sentence);
//now you can check if any words in the array eqauls a name in your database
//create a foreach loop to check all words
foreach($array as $word) {
//search if the word contains in the array
if(in_array($word, $names)) {
//this word is a searched name
print_r("Word ".$word." is a name!\n");
}
else {
//this word isn't a name
}
}
In the If/Else you can code a custum handler. Notice if the sentence ends with a dot that the last word have at the last char a dot(.). You can check it and remove the dot with the substr function.
I don't test the code.

Try stored procedure. I have tested this query for random paragraph and get following execution time with three option
CREATE PROCEDURE FindInDB
#INSTR varchar(255)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #SEPERATOR as VARCHAR(1)
DECLARE #SP INT
DECLARE #VALUE VARCHAR(1000)
SET #SEPERATOR = ' '
-- Create Temporary table add all words in it
CREATE TABLE #tempTab (name varchar(50) not null)
WHILE PATINDEX('%' + #SEPERATOR + '%', #INSTR ) <> 0
BEGIN
SELECT #SP = PATINDEX('%' + #SEPERATOR + '%',#INSTR)
SELECT #VALUE = LEFT(#INSTR , #SP - 1)
SELECT #INSTR = STUFF(#INSTR, 1, #SP, '')
INSERT INTO #tempTab (name) VALUES (#VALUE)
END
-- Total execution time 15 0 7.5000
--SELECT [Name]
--FROM [tblName]
--where Name IN (SELECT name FROM #tempTab)
--Total execution time 15 15 0 10.0000
--SELECT distinct [tblName].[Name]
--FROM [tblName]
--inner join #tempTab on #tempTab.name = tblName.Name;
--Total execution time 15 15 15 15 0 12.0000
SELECT [Name]
FROM [tblName]
where EXISTS (SELECT name FROM #tempTab
where #tempTab.name = tblName.Name )
DROP TABLE #tempTab
END
GO

Related

Increment remaining row values in a column based on changing one value

I am trying to create a round robin scenario when new leads come in.
When a lead comes in, the following table named "round_robin" will find the position '1' and send the lead data there
Name Type Attributes Null Default Extra
id int(11) No None AUTO_INCREMENT
on_off text Yes NULL
cname text Yes NULL
position int(11) Yes NULL
email varchar(100) Yes NULL
I have some knowledge of PHP so if some coding I used is way off, thats likely why.
This is the code I've started on.
$round_robin_companies = "SELECT * FROM round_robin";
$position_one = "SELECT position FROM round_robin WHERE postion = '1' ";
$query = "SELECT * FROM round_robin WHERE position = '$position'";
$result = mysql_query($query);
if ($result === 1) exit();
else {
UPDATE $position_one SET position='$row_count';
while ($query <= $row_count) {
$row_count++;
}
}
Basically, when a new row is added in a table called leads, I need Company One position to change to $row_count (3) and all the remaining positions to increment down one.
So Company Two position would be 1 and be next in the queue and Company Three would become 2. I want to use row count because I will be adding more companies in the future.
id on_off cname position email
1 on Company One 1 C1#email.com
2 on Company Two 2 C2#email.com
3 on Company Three 3 C3#email.com

Getting the missing IDs from a table by storing the records into an array and compare the set of numbers with a for loop

I'm currently working on a program that gets the missing IDs of a table and the idea that I come up with is that by storing the IDs into an array and use a for loop to check if a number exists in the array and if it's existing then it is classified as a missing ID. I also used the php function - in_array() to check if a number exists in the array.
This is the code that I came up with, but I ended up with just displaying the numbers from the for loop.
<?php
include 'dbconnect.inc'; //just to the the dbconnect for connecting into the database.
$numbers = array(1, 2, 4, 6, 7, 9);
$arrlength = count($numbers);
$query = "SELECT id FROM existing";
$result = mysqli_query($conn, $query);
$existing = array();
while ($row = mysqli_fetch_assoc($result)) {
$existing[] = $row;
}
for ($i=0; $i<7358; $i++) {
if (in_array($i, $existing)) {
echo $i . " is a missing ID <br>";
} elseif(!in_array($i, $existing)) {
echo $i . " exists in the table <br>";
}
}
?>
I prefer this solution than using the temporary tables in an SQL because it takes more than to load the query and it would not be good for a webpage.
Hope that you could help me. Thanks!
From this answer:
To get missing ranges:
SELECT a.id+1 AS 'Missing From', MIN(b.id)-1 AS 'Through'
FROM existing AS a
JOIN existing AS b ON a.id < b.id
GROUP BY a.id
HAVING a.id+1 < MIN(b.id)
fiddle
User variables are only evaluated when sent, so using a HAVING NOT (gap_from=0 AND gap_to=0) clause isn't possible as an optimization (see user variables manual). A such we use the "sending" to be sending to the temporary table to save a larger time full of data that is about to be discarded.
The temporary table uses the primary key ensure there will only be one (0,0) entry that occurs when the there is no gap. Inserting subsequent existing entries (0,0) gets ignored resulting in a minimal table of gaps.
The remainder of the table is the gaps in the sequence:
create table existing (id int unsigned not null)
insert into existing values (3),(5),(6),(7),(8),(19),(20),(21),(30)
set #last=0
CREATE TEMPORARY TABLE v (gap_from int unsigned, gap_to int unsigned, next int unsigned, PRIMARY KEY(gap_from, gap_to))
IGNORE SELECT IF(#last=id, 0, #last) as gap_from,
IF(#last=id, 0, id-1) as gap_to,
#last:=id+1 as next
FROM existing ORDER BY id
select gap_from,gap_to from v where NOT (gap_from=0 AND gap_to=0)
gap_from | gap_to
-------: | -----:
0 | 2
4 | 4
9 | 18
22 | 29
If you don't want the first gap, the one between 0 and the first entry in the table:
select gap_from,gap_to from v where gap_from!=0
db<>fiddle here

To append comma separated value no duplicates in mysql update Query

I am storing table data as comma separated values like this
id name fk_id
1 abc 2,4,6
2 def 2,7,8
Now, I want to use CASE WHEN or some function in Update Query of MySQL which updates the field if no duplicate value:
For example, same value for fk_id then ignores else update like if 10 for id 1 then update but if 7 for id 2 then ignore
id name fk_id
1 abc 2,4,6,10
2 def 2,7,8
I tried the following code:
if(
find_in_set($fk_id,fk_id),
fk_id,
CONCAT_WS(',', fk_id, $fk_id)
)
But not working.
Just update your code like as
set fk_id = if(find_in_set($fk_id,fk_id),
fk_id,
CONCAT(fk_id, ',', $fk_id)
)
Try this :
$sql = "
UPDATE `test`
SET `fk_id` = CONCAT(fk_id, ',','" . $fk_id . "')
WHERE `fk_id` REGEXP ',?(" . $fk_id . "),?'
";
NOTE : REGEXP is not the best option when it comes to speed.

Add new last number automatically mysql

I have this id number in one column of my table,
0907003
0907004
0907005
1008005
1008006
1008007
1009001
1009002
1009003
When I add new value of 1009, it will add last three number of 004 because the last number begin with 1009 (10-09) is 003.
Or if I add new value of 1008, it will add last three number of 008
because the last number begin with 1008 (10-08) is 007.
Or if I add new value of 0907, it will add last three number of 006
because the last number begin with 0907 (09-07) is 007.
How to do this?
Many thanks in advance!
$front_id = $this->input->post('gameid'); //09
$middle_id = $this->input->post('netid'); //07
//$last_id will be generate automatically by sql
$forID = $front_id.$middle_id;
$sql = "INSERT INTO table ('colum') VALUES (".$forID.")"
You have to insert new id manually
$max_of_letsay1009 = mysql_result(mysql_query("select MAX(id) from table where id like '1009%'"),0);
// get the last 3 digits
$new_number = (int)substr($max_of_letsay1009,-3) + 1;
or you can try this too:
$new_id_of_letsay1009 = mysql_result(mysql_query("select MAX(id)+1 from table where id like '1009%'"),0);
this is just my idea, not yet tested and no error checking
You try this below query
If your value is 1009
SELECT MAX(RIGHT(ID,4))+1 FROM TableName WHERE LEFT(ID,4) = '1009'
It will return the max number of that series.
Try this query for dynamic ID length
SELECT MAX(RIGHT(ID,len(id)-LEN('1009')))+1 FROM #TEMP WHERE LEFT(ID,LEN('1009')) = '1009'
You can also use this query as sub query for the insert statement's ID column.
It is possible if it is not Auto_Increment coulmn.
Just need to write logic on insert time.

Getting the MySQL WHERE IN delimited string

I've been recently stuck on an issue I've been having involving sending a string of comma separated values into a stored procedure. My issue is that when I execute my stored procedure in PHP it uploads the values with quotes around it like so;
CALL `rankingInformation`('145', '5', '', '37,38,39,40,41')
Failing to add the quotes would make MySQL interpret them as extra parameters.
However it's mean't to be like in the WHERE IN on the query side it's meant to be formatted like so
'37', '38', '39', '40', '41'
Here is the query below, can anyone spot anything I can do? Here is what I've got up to now.
CREATE DEFINER = `root`#` localhost` PROCEDURE` rankingInformation`(IN` surveyId` INT, IN` filterCounting` INT, IN` survey_filter_id` INT, IN` question_limit` TEXT)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'Gathers all the ranking information for a given ID'
BEGIN
DECLARE sfi int(2);
DECLARE ql TEXT;
IF(survey_filter_id = '') THEN
SET sfi = (SELECT sf2.survey_filter_id FROM survey_filters AS sf2 WHERE sf2.survey_id = 145 AND sf2.survey_filter_id IS NOT NULL LIMIT 1);
ELSE
SET sfi = survey_filter_id;
END IF;
SELECT
COUNT( * ) AS total, CONCAT(su.first_name, ' ', su.last_name) as full_name, sf.survey_filter_id, sf.survey_filter_name, qa.question_id, su.temp_group_1 AS department
FROM questions_answers AS qa
INNER JOIN survey_users AS su ON su.survey_users_id = qa.survey_users_id_answer
INNER JOIN survey_filters AS sf ON sf.survey_id = surveyId
WHERE qa.survey_id = surveyId
AND qa.question_id IN (splitAndTranslate(question_limit, ','))
AND sf.survey_filter_id = sfi
GROUP BY qa.survey_users_id_answer
HAVING total > filterCounting
ORDER BY total DESC;
END
splitAndTranslate
Here is a function I found which is mean't to do the job, I am not sure I am far away.
CREATE DEFINER=`root`#`localhost` FUNCTION `splitAndTranslate`(`str` TEXT, `delim` VARCHAR(1))
RETURNS text CHARSET utf8
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'Fixes all Where IN issues'
BEGIN
DECLARE i INT DEFAULT 0; -- total number of delimiters
DECLARE ctr INT DEFAULT 0; -- counter for the loop
DECLARE str_len INT; -- string length,self explanatory
DECLARE out_str text DEFAULT ''; -- return string holder
DECLARE temp_str text DEFAULT ''; -- temporary string holder
DECLARE temp_val VARCHAR(255) DEFAULT ''; -- temporary string holder for query
-- get length
SET str_len=LENGTH(str);
SET i = (LENGTH(str)-LENGTH(REPLACE(str, delim, '')))/LENGTH(delim) + 1;
-- get total number delimeters and add 1
-- add 1 since total separated values are 1 more than the number of delimiters
-- start of while loop
WHILE(ctr<i) DO
-- add 1 to the counter, which will also be used to get the value of the string
SET ctr=ctr+1;
-- get value separated by delimiter using ctr as the index
SET temp_str = REPLACE(SUBSTRING(SUBSTRING_INDEX(str, delim, ctr), LENGTH(SUBSTRING_INDEX(str, delim,ctr - 1)) + 1), delim, '');
-- query real value and insert into temporary value holder, temp_str contains the exploded ID
#SELECT ImageFileName INTO temp_val FROM custombu_roomassets_images WHERE ImageID=temp_str;
-- concat real value into output string separated by delimiter
SET out_str=CONCAT(out_str, temp_val, ',');
END WHILE;
-- end of while loop
-- trim delimiter from end of string
SET out_str=TRIM(TRAILING delim FROM out_str);
RETURN(out_str); -- return
END
What did you do with FIND_IN_SET? Building on spencer7593's answer, it should work if you replace:
AND qa.question_id IN (splitAndTranslate(question_limit, ','))
with
AND FIND_IN_SET(qa.question_id, question_limit)>0
The commas within a string value are not interpreted as SQL text in the context of a SQL IN comparison. Your query is essentially of the form:
AND qa.question_id IN ('some,long,string,value')
And any comma characters within the string are just data; just characters that are part of the string. This is effectively the same as an equals comparison.
The MySQL FIND_IN_SET function might be a way for you to perform the comparison you want.
http://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_find-in-set
AND qa.question_id IN (splitAndTranslate(question_limit, ','))
Put these lines instead of the above line
AND (qa.question_id = question_limit
OR qa.question_id LIKE CONCAT(question_limit,',%')
OR qa.question_id LIKE CONCAT('%,',question_limit,',%')
OR qa.question_id LIKE CONCAT('%,',question_limit))
Then you don't need the splitAndTranslate Function anymore . .

Categories