How to know how many words a paragraph contains in MySQL? - mysql

What MySQL function can I use?
for example,
What Mysql function can I use?
contains 6 words.

There isn't a built in a function that I know if, but I found this in the comments of MySQL's String Functions documentation:
I was looking for word_count("string") in mysql, finally came up with an user defined function which is very usefull for me, note: I used for actual space.
DROP FUNCTION IF EXISTS word_count;
CREATE FUNCTION word_count (f_string text(5000)) RETURNS smallint(10)
BEGIN
DECLARE new_string text(5000);
WHILE INSTR(f_string,'<space><space>')>0
DO
SET new_string=(select REPLACE(f_string,'<space><space>','<space>'));
SET f_string=new_string;
END WHILE;
RETURN (select LENGTH(TRIM(f_string))-LENGTH(REPLACE(TRIM(f_string),'<space>',''))+1);
END
//
Here is the result
mysql> select word_count("Balaji Devarajan") WORD_COUNT;
+------------+
| WORD_COUNT |
+------------+
| 2 |
+------------+
1 row in set (0.00 sec)
mysql> select word_count(" Balaji Devarajan ") WORD_COUNT;
+------------+
| WORD_COUNT |
+------------+
| 2 |
+------------+
1 row in set (0.00 sec)
mysql> select word_count("Balaji Devarajan") WORD_COUNT;
+------------+
| WORD_COUNT |
+------------+
| 2 |
+------------+
1 row in set (0.01 sec)

There is no function to count words in MySQL (or ANSI SQL, or any other DBMS I'm familiar with).
You could maybe fake it by counting the number of spaces in the text using a string replace:
SELECT LENGTH(colname)-LENGTH(REPLACE(colname, ' ', ''))+1 AS wordcount FROM tablename;
This isn't really a word count but would work as long as every word is separated by exactly one space.
To get better word matching you would need a regex, but there is no regex replace in MySQL so you can't use the replace trick. You could select specifically 6-word long values using a REGEXP/RLIKE match though:
SELECT * FROM tablename WHERE colname RLIKE '^[^[:alnum:]]*[[:alnum:]]+([^[:alnum:]]+[[:alnum:]]+){5}[^[:alnum:]]*$';
Either way, this is slow. It will have to do a string replace or regex match on every row of the table every time you do the query. If number-of-words is a query you are doing often you will want to optimise (denormalise) the table by adding a (possibly indexed) column to store the number of words.

Related

can a mysql select query in C language return a field with the special characters escaped?

1- string = a'b"c\d
2- escaped_string = a\'b\"c\\d
3- make an insert query that inserts escaped_string in some table field.
4- make a select query that returns the inserted value.
The returned value is: a'b"c\d
Is there a way to get the select query to return a\'b\"c\\d ?
(I understand that i can escape it again).
You can use the QUOTE() function of mysql:
mysql> select data from x;
+---------+
| data |
+---------+
| a'b"c\d |
+---------+
1 row in set (0.00 sec)
mysql> select quote(data) from x;
+-------------+
| quote(data) |
+-------------+
| 'a\'b"c\\d' |
+-------------+
1 row in set (0.00 sec)
This should exactly do what you are looking for. Note that the " doesn't need to be escaped here, so QUOTE() doesn't escape it, too.

difference between find_in_set and and locate

I have product tables in my database
Product table structure:
product_id | testid
------------------------------------
1 11,12,13
2 2,4
Below is my FIND_IN_SET query:
SELECT product_id FROM product
WHERE FIND_IN_SET(3, testid) > 0;
Output
0
Below is my LOCATE query:
SELECT product_id FROM product
WHERE LOCATE(3, testid) > 0;
output
1
My question
What is difference between FIND_IN_SET and LOCATE and what is the best way to find id in column
To put it in simple technical terms(PHP terminology), find_in_set is like substring function of PHP. It will accept a substring and a string as parameters, and return 1 if the substring is found within the string. It will return 0 if substring is not found.
On the contrary, LOCATE() returns the position of the first occurrence of a string within a string. It accepts, a substring and a string as parameters.
I think in your use case, find_in_set is the one you should go for. Because this is the one. find_in_set will return 1 if 3 is found in a row, where as locate will first occurance of 3 in the string even if it finds 31 or 300 as first element.
Difference between LOCATE() and FIND_IN_SET() Function
When using LOCATE() function for integers, suppose we need 1 to return from LOCATE() if integer 3 is in the set 1,2,3,4,5,.. the following MySQL commands can be written:
mysql> SELECT IF(LOCATE(3,'1,2,3,4,5,6,7,8,9')>0,1,0);
+-----------------------------------------+
| IF(LOCATE(3,'1,2,3,4,5,6,7,8,9')>0,1,0) |
+-----------------------------------------+
| 1 |
+-----------------------------------------+
1 row in set (0.06 sec)
The above command working rightly because the set contains the number 3 , but if we write the following commands, look what happened
mysql> SELECT IF(LOCATE(3,'11,12,13,14,15')>0,1,0);
+--------------------------------------+
| IF(LOCATE(3,'11,12,13,14,15')>0,1,0) |
+--------------------------------------+
| 1 |
+--------------------------------------+
1 row in set (0.02 sec)
Above the 3 is not present as a number three(3) in the given set, though the LOCATE() returns 1.
To avoid this type of situation you can use the FIND_IN_SET() function. Here is the example below:
mysql> SELECT IF(FIND_IN_SET(3,'11,12,13,4,5,6,7,8,9')>0,1,0);
+-------------------------------------------------+
| IF(FIND_IN_SET(3,'11,12,13,4,5,6,7,8,9')>0,1,0) |
+-------------------------------------------------+
| 0 |
+-------------------------------------------------+
1 row in set (0.05 sec)
So, LOCATE() function is very much suitable for string but not as much suitable for integer.
Examples, credits and some more information you can find here
So in your example FIND_IN_SET return 0 because there is no 3 in the given set, but LOCATE() returns 1 it treat the given set as a string but not a comma separated value, and the 3 present in the number 13

Mysql query with single quotation mark in the where clause

I have this query:
SELECT * FROM tbname WHERE LCASE(title) LIKE '%l\'infinito%'
The value into the table contains slash before quote.
Why the query returns no results?
thanks
The escaping is correct. You actually do not need LCASE since LIKE is not case sensitive (at least not on my Linux system):
mysql> SELECT 'L\'Infinito' LIKE '%l\'infinito%';
+------------------------------------+
| 'L\'Infinito' LIKE '%l\'infinito%' |
+------------------------------------+
| 1 |
+------------------------------------+
1 row in set (0.00 sec)
Maybe you want to search L'Infinito, with an 'n'. Or maybe the title seems to contain a single quote, but it is one of those never sufficiently damned Windows Word reverse English quotes.
Or maybe there is a space in the title after the quote. In many fonts, this is not immediately visible.
L' infinito
Can you search using '%ifinito%' (or '%infinito%'), and verify that the found row does indeed contain a single ASCII quote?
UPDATE
...and finally, maybe the database is wrong. To wit:
mysql> CREATE TABLE catalogo (title varchar (32));
mysql> INSERT INTO catalogo VALUES ('L\'Infinito');
mysql> SELECT * FROM catalogo;
+------------+
| title |
+------------+
| L'Infinito |
+------------+
If you run the same SELECT as before, does MySQL return L'Infinito without escaping? Because if you have instead
+-------------+
| title |
+-------------+
| L\'Infinito |
+-------------+
then the title has been saved wrong, escaping the quote sign TWICE. So there is an escape sign between the L and the quote, and you would have to search for
L\\\'Infinito
to "neutralize" the error.
Try this:
SELECT * FROM tbname WHERE LCASE(title) LIKE '%l\\\'infinito%'
The following query will answer your question:
string s="'infinito";
s=s.Replace("'", "''");
SELECT * FROM tbname WHERE LCASE(title) LIKE '%s%'

About mysql regex,how do I search and return string use mysql regex

My table filed's value is "<script type="text/javascript"src="http://localhost:8080/db/widget/10217EN/F"></script>",
I want to analyse this string and fetch the id 10217,how to do use mysql regex?
I know python regex group function can return the id 10217,but i'm not familiar with mysql regex.
Please help me,Thank you very much.
MySQL regular expressions do not support subpattern extraction. You will probably have better luck iterating over all of the rows in your database and storing the results in a new column.
As far as I know, you can't use MySQL's REGEXP for substring retrieval; it is designed for use in WHERE clauses and is limited to returning 0 or 1 to indicate failure or success at a match.
Since your pattern is pretty well defined, you can probably retrieve the id with a query that uses SUBSTR and LOCATE. It will be a bit of a mess since SUBSTR wants the start index and the length of the substring (it would be easier if it took the end index). Perhaps you could use TRIM to chop off the unwanted trailing part.
This query get the Id from the field
SELECT substring_index(SUBSTRING_INDEX(testvar,'/',-3),'EN',1) from testtab;
where as testtab - is table name , testvar - is field name
inner substring get string starts with last 3 / which is
mysql> SELECT SUBSTRING_INDEX(testvar,'/',-3) from testtab;
+----------------------------+
| SUBSTRING_INDEX(testvar,'/',-3) |
+----------------------------+
| 10217EN/F"> |
| 10222EN/F"> |
+----------------------------+
2 rows in set (0.00 sec)
outer substring get
mysql> SELECT substring_index(SUBSTRING_INDEX(testvar,'/',-3),'EN',1) from testtab;
+----------------------------------------------------+
| substring_index(SUBSTRING_INDEX(testvar,'/',-3),'EN',1) |
+----------------------------------------------------+
| 10217 |
| 10222 |
+----------------------------------------------------+
2 rows in set (0.00 sec)

ActiveRecord / MySQL Select Condition Comparing String Components

I have a string that is defined as one or more dot-separated integers like 12345, 543.21, 109.87.654, etc. I'm storing values in a MySQL database and then need to find the rows that compare with a provided value. What I want is to select rows by comparing each component of the string against the corresponding component of the input string. With standard string comparison in MySQL, here's where this breaks down:
mysql> SELECT '543.21' >= '500.21'
-> 1
mysql> SELECT '543.21' >= '5000.21'
-> 1
This is natural because the string comparison is a "dictionary" comparison that doesn't account for string length, but I want a 0 result on the second query.
Is there a way to provide some hint to MySQL on how to compare these? Otherwise, is there a way to hint to ActiveRecord how to do this for me? Right now, the best solution I have come up with is to select all the rows and then filter the results using Ruby's split and reject methods. (The entire data set is quite small and not likely to grow terribly much for the foreseeable future, so it is a reasonable option, but if there's a simpler way I'm not considering I'd be glad to know it.)
You can use REPLACE to remove dots and CAST to convert string to integer:
SELECT CAST(REPLACE("543.21", ".", "") AS SIGNED) >= CAST(REPLACE("5000.21", ".", "") AS SIGNED)
mysql> SELECT '543.21' >= '5000.21';
+-----------------------+
| '543.21' >= '5000.21' |
+-----------------------+
| 1 |
+-----------------------+
1 row in set (0.00 sec)
mysql> SELECT '543.21'+0 >= '5000.21'+0;
+---------------------------+
| '543.21'+0 >= '5000.21'+0 |
+---------------------------+
| 0 |
+---------------------------+
1 row in set (0.00 sec)
This indeed only works for valid floats. Doing it for more then 1 dot would require a LOT of comparing of SUBSTRING_INDEX(SUBSTRING_INDEX(field, '.', <positionnumber you're comparing>), '.', -1) (with a manual repeat for the maximum number of position's you are comparing)