get first 3 alphanumeric characters (only numbers or letters) - mysql

I have a table which holds a field, title, I need to get first 3 alphanumeric characters of each title. Some of the values of title have ",',\t,\n, or whitespace prepended - this should be ignored.
+--------+-----------------------------------------+---------------------+
| id | title | desired output |
+--------+-----------------------------------------+---------------------+
| 1 | "abcd" | abc |
| 2 | 'lostworld | los |
| 3 | \tsonof | son |
| 4 | 12amrt | 12a |
+--------+-----------------------------------------+---------------------+
desired output is the output I am looking for. If anyone can suggest generic query which can handle all cases that would be great.
Looking for solution using MySQL only.

Your best bet is to use a regex user-defined function.
The built-in regexp functions only support matching; not string replacing like you want here

Related

Mysql - BIGINT value is out of range in error using substring_index

select substring_index(SUBSTRING_INDEX(title, ' ', title+1), ' ',-1) as word ,
COUNT(*) AS counter
from feed_collections
group by word
ORDER BY counter DESC;
The table has 1785123 rows and I thing this is the problem.
This is the error query (1690): BIGINT value is out of range in '(feed_collections.title + 1)' and I don't know how to fix it.
The query worked until around 1500000 rows.
The table contains 3 columns: title(text), url(text), date(datetime).
The code is finding most common words in column title
Example:
Table
+----------------------------------+-----------------+
| title | url |
+----------------------------------+-----------------+
| the world of ukraine | www.ab |
| count the days until christmas | www.abc.com |
| EU and NATO wants to use bombs | www.abcd.com |
| Ukraine needs help from NATO | www.abce.com |
+----------------------------------+-----------------+
Result
+------+-------+
| word | total |
+------+-------+
| nato | 5 |
| of | 14 |
| and | 11 |
| To | 9 |
| that | 7 |
| ukraine | 2 |
| EU | 1 |
+------+-------+
I adapted the code from here:
How to find most popular word occurrences in MySQL?
This works with small data. Seems to be a problem when tries to filter large data.
What I'm trying to achive in the future is to find most common words in the title column grouped by 1,2,3,4,5,6,7 words.
It will exists a select box to select how many words to use.
Example:
I will select to find most common words with 4 words.
Title: 1. Nato is using force , 2. Eu and Nato is using force.
Results with 4 words:
'nato is using force' found 2 times in title.
Any idea how to fix or how to do a query for this?
I'm working with laravel, a solution would be to create a php method...

Find the ranking for a row with multiple values separated by a comma in mysql

I have a database in mysql which has three rows, these rows has concatenated multiples values(values separated by a comma) already in it. I want to strike the rank using find_in_set function or any better function to get the positions.
Table
id | NUMBERS |
1 | 30,40,10 |
2 | 58,29,21 |
3 | 18,25,51 |
I want to rank each row in this format
id | NUMBERS | POSITION |
1 | 30,40,10 | 2,1,3 |
2 | 58,29,21 | 1,2,3 |
3 | 18,25,51 | 3,2,1 |
I Know the data representation and structure is wrong, but the data i have currently is made like the above and has a lot of data in it, meaning changing the structure would take me a lot of time, although I would change it later.
I need a workaround idea as to how to do this. I would be grateful for your support thanks.

"where" or "like" clause is better for using index

I have a table with columns of type SET e.g SET('abc','def','ghi') wich store the data like "abc,ghi" and I index these columns. So when I want to find "def" or "ghi" I have to use LIKE "%def%" but I read about "%" that if you use it as first character mysql doesn't use index for search. Waht should I do? should I change the type to enum and store each value in separate row with an ID like this:
+---------+
| column |
+---------+
| abc |
| abc,ghi |
| abc,def |
| ghi,def |
+---------+
change to:
+----+--------+
| ID | column |
+----+--------+
| 1 | abc |
| 2 | abc |
| 2 | ghi |
| 3 | abc |
| 3 | def |
| 4 | ghi |
| 4 | def |
+-------------+
or is there any thing to manipulate index to store each word separately?
The correct function to find an item in a set is FIND_IN_SET. Sets are stored as bit maps, not as strings, and FIND_IN_SET will not have to convert it to a string before matching like LIKE would. But it still won't be able to use an index.
Your second schema is the proper way to normalize the data. You can put an index on the column column, and queries that look for a value will be efficient. Whether to use an ENUM or VARCHAR for this column is a subject of intense debate within the database community.

Using MySQL how can I create a list of all words in a set of strings?

Let's say I've got a table like this:
| RowID | LongString |
----------------------------------------
| 1 | This is a really long string |
| 2 | This is a shorter string |
How can I get a list of distinct words used in all the rows such as below:
| Result: |
-----------
| This |
| is |
| a |
| really |
| long |
| string |
| shorter |
From MySQL docs:
MySQL does not include a function to split a delimited string. Although separated data would normally be split into separate fields within a relation data, spliting such can be useful either during initial data load/validation or where such data is held in a text field.
So there is not ready-to-go solution. If I were you, I would split such string after fetching it from DB (it is easy to do in PHP, Java C# and so on).
Howewer on this site someone has wrote procedure for such task. Check it out. It is in comments section below.

How to make a field of a DataBase as array?

I want to have a column in a database that can contain multiple entries. Is it possible to have to define the type of the column as an array (fixed-sized array or some dynamic collection) so that it can store multiple entries.
If you require various values to be stored together, in a single field, then you will likely be best off storing them as a delimiter-separated string of values:
+----------------------------------+
| PRODUCTS |
+----------+-----------------------+
| Product | Colors |
+----------+-----------------------+
| Notebook | blue,red,green,orange |
+----------+-----------------------+
This is usually not what youw want though. Generally-speaking, the idea solution is to create relationships between tables. For instance:
+---------------+
| PRODUCT |
+----+----------+
| ID | Product |
+----+----------+
| 1 | Notebook |
+---------------+
+---------------+
| COLORS |
+----+----------+
| ID | Color |
+----+----------+
| 1 | Blue |
+---------------+
| 2 | Red |
+---------------+
| 3 | Green |
+---------------+
+---------------------+
| PRODUCTCOLORS |
+-----------+---------+
| ProductID | ColorID |
+-----------+---------+
| 1 | 1 | Notebook, Blue
+-----------+---------+
| 1 | 3 | Notebook, Green
+-----------+---------+
yes, in a typical relational design, you would have a 1:N (1-to-many) relationship between 1 table and another. each row in the first table represents a collection, each row in the second table is an element in a collection and references the first table.
a comma-separated list, serialize, or a url-encoded string is also a good solution as the other answers point out...
No, but what server side language are you using?
If using PHP you can use
$serializedArray = serialize($myArray);
And then insert that value into the db. To get it back out use unserialize();
This is pretty much the same answer as above (have a delimited string), but you could also save the text in that column as XML. Depending on the database you are using, that could be easy or tedious.
As pointed out above, is you obviously lose any aspect of being able to manage the data integrity from your DB layer (easily).