Concatentate all rows / alt. find using a regex across all rows - mysql

I have a table like this:
+----+---------------------------------------------------+
| id | value |
+----+---------------------------------------------------+
| 1 | My favourite website is http://stackoverflow.com/ |
| 2 | This text doesn't have a link! :( |
| 3 | Hi! A link! http://www.google.com/ |
+----+---------------------------------------------------+
But of course with many rows. What I really want is a list of all the URLs in the fields. In reality they are blog posts, so some will have more than one link. I'm only interested in external links (i.e. start with (/http(s)?/) ).
So, my first thought was to perform a SQL query that returns something like:
My favourite website is http://stackoverflow.com/,This text doesn't have a link! :(,Hi! A link! http://www.google.com/
so I can use regex in PHP.
How do I write that query?
Alternatively, it would be great to go straight to list of URLs with SQL, but I suspect that might be too hard due to the multiple links thing.
Any ideas?

use GROUP_CONCAT
SELECT GROUP_CONCAT( value )
FROM tableName
SQLFiddle Demo
OTHER SOURCE
GROUP_CONCAT

Related

MySQL - Searching for CC numbers

I inherited a MySQL server that has CC numbers stored in plaintext. due to PCI requirements, I need to find the numbers and mask them. The trick is they are stored in a field with other text as well. I need to find a way to search for cc numbers and change just those, not the rest of the text.
I have tried the masking feature in MySQL, but it doesn't work for this version. I also looked up a few different sites but can't seem to find anything that will really help with my particular instance.
Edit
to explain better. the previous admin didn't tell the operators to not take CC info through the live chat system. The system is using SSL but the chat history is stored in plain text in a MySQL DB. The company isn't PCI compliant (as far as getting scanned and SAQ is concerned) so we cannot have CC numbers stored anywhere. but the numbers are given in the middle of a conversation. If they were in their own column then that wouldn't be a big deal.
EDIT
I have tried using regexp to just try and search for CC #'s but now I am getting an operand error, which is lazy quantifiers I believe.
SELECT * FROM table_name Where text regexp '^4[0-9]{12}(?:[0-9]{3})?$'
Any Ideas?
You could potentially use a regular expression to search for 16-19 consecutive characters with (using LIKE if you have the numbers separated from the text, or just REGEXP):
The example is given here (where 5 is the number of items to search for, and ^$ requires it to be those at the beginning and end):
mysql> SELECT * FROM pet WHERE name REGEXP '^.{5}$';
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
Would end up something like:
REGEXP '^([0-9]{16|17|18|19})$'
https://dev.mysql.com/doc/refman/8.0/en/pattern-matching.html
And lookie here too:
Regex to match a digit two or four times

MYSQL - searching for some strings

I have a table with lots of features, but I used features as just one column.
tbl_shop
id | name | feature
I used php implode to save the data to feature, and it will show like this
id | name | feature
1 | shop_1 | wifi,smarttv,cr
When I use LIKE to search for the data I can actually get the shop properly if I just search for one feature like wifi
the thing is if i tried to search for wifi,smarttv or smarttv,cr there is no problem, but when I tried to search wifi,cr that time it would not find the shop, is there any way of searching data like this in MySQL ?
You can insert a % in between your shops (or partial shops)
select * from table where feature like '%wifi%cr%';

MySQL. Way to compose query with "LIKE" which will work similar as url regular expression

for example I have table 'urls'
urls:
___________________________________________
| id | href |
+--------+--------------------------------|
| 1 | /a/b/c/d/e/f/g/ |
+--------+--------------------------------|
| 2 | /a/b/g/ |
+--------+--------------------------------|
| 3 | /a/c/g/ |
+--------+--------------------------------|
| 4 | /a/d/g/ |
+--------+--------------------------------|
| 5 | /a.php?code=g |
+--------+--------------------------------|
| N | anyUrlString |
+--------+--------------------------------|
I wanna select urls which have special format, for example (like ROUTE in popular PHP frameworks)
"/a/#anyparam/g"
so: WHERE href LIKE '/a/%/g'
but it also will select row with id 5, 1..
How to compose LIKE statement to I can get only URI enabled values in #anyparam ?
must be something like this /a/[%, but not ('/','?','\')]/g but what exactly?
Thanks for any proposition!
P.S. Do not propose to use regular expression (it don't use indexes)!
Can you use multiple clauses?
LIKE '/a/%/g' AND NOT LIKE '/a/%?%/g' ....
Chain some "exceptions" together, attacking cases that do not match. It's hard to come up with a general case, with your limited sample set. An EXPLAIN will show if Indexes are still in use.
String and pattern taken from your code:
SELECT 1 WHERE '/a.php?code=g' LIKE '/a/%/g'
^ should not give you anything, since the string your testing doesn't end in /g, it ends with =g.
But an often overlooked ability of LIKE is negative character-classes. Unfortunately they are not variable-length, they always only represent 1 character, but you could REPEAT() them:
LIKE '/a/' + REPEAT('[^/?\]', LEN(#someVar)) + '/g'

SELECTing (almost) duplicate rows

My table looks something like this:
| id (int) | sentence (varchar) |
I want to find all rows that are almost the same except for one particular word. Eg:
| 230 | test |
| 321 | test sth |
...
| 329 | is (sth) it?
| 923 | is it?
The word that can be different is sth in this case. Ideally I could use some sort of "array" with the list of words that can be different.
Is this something I could do purely in SQL?
Just an untested quick shot, sorry, but I think you could do something like
SELECT * FROM table GROUP BY REPLACE(text, 'sth', '')
You can use SOUNDEX. So with the examples that you gave, these queries:
SELECT SOUNDEX('test')
SELECT SOUNDEX('test sth')
SELECT SOUNDEX('is (sth) it?')
SELECT SOUNDEX('is it?')
return these results:
T230
T230
I200
I200
That means that the first two and the second two sound like each other. What I can't be sure of is how well this will work with your actual data, you're just going to have to try it.

Selecting the most popular keyword in a mysql database

I have a column called keywords where users enter up to 4 keywords separated by a coma, ie:
----------------------------------
userId | kewords |
----------------------------------
01 | php,css,html,mysql |
02 | wordpress,css,drupal,xx |
03 | mysql,html,wordpress,css|
----------------------------------
I'm trying to figure out a query to select all the keywords from everyone, explode them by the coma and then count how many there are of each.
I know I can do this quite easily with PHP but I though there might be a way for mysql to do it...
Any ideas?
Try to normalize the data, ie store 4 rows instead of one for each user.
It also possible to split a string into a temporary table but I'm not sure that will help you much. Originally I found this source on mysql forge but that has been shut down so here is a similar code
http://www.pnplogic.com/blog/articles/MySQL_Convert_Delimited_String_To_Temp_Table_Result_Set.php