Search for rows containing regex with my matchstring - mysql

My users enter a regular expression of URLs in the app. I have to return the rows with regular expressions that matched given url.
I have a table like this:
+----+-----------------------+--------------------------+
| id | Survey | URL Regexp |
+----+-----------------------+--------------------------+
| 1 | User Age survey | http://*.google.com/* |
| 2 | Payment intent survey | http://mail.google.com/* |
| 3 | User Country info | *reader.google.com* |
| 4 | Company information | http://facebook.com/* |
| 5 | Satisfaction survey | http://*twitter.com/* |
+----+-----------------------+--------------------------+
I want to run a query against a url, http://mail.google.com/index.html and see (1, 2) as a result (i.e. User Age Survey and Payment intent survey records).
I want a run a query like this:
SELECT * FROM surveys where MATCH_REGEXP('http://mail.google.com/index.html')
I wasn't able to find any documentation for such expression. What would be the best way to solve this?

Here's a working sqlfiddle example.
Given you have this data:
CREATE TABLE surveys (
id int auto_increment primary key,
survey varchar(30),
url_regex varchar(30)
);
INSERT INTO surveys (survey, url_regex) VALUES
('User Age survey', 'http://.*.google.com/*'),
('Payment intent survey', 'http://mail.google.com/*'),
('User Country info', '*reader.google.com*'),
('Company information', 'http://facebook.com/*'),
('Satisfaction survey', 'http://*twitter.com/*');
You can do this query to achieve what you want:
SELECT id FROM surveys
WHERE 'http://mail.google.com/index.html' REGEXP url_regex;
The result will be:
1
2
Please, note that in order to achieve desired result, i.e. (1, 2), "User Age survey" regular expression had to be fixed by prepending a dot before the first asterisk.

Related

MySQL - How to order duplicate rows in a key value pair table based on multiple columns?

So I have the following key/value pair table, where users submit data through a form and each question on the form is added to the table here as an individual row. Submission_id identifies each form submission.
+----+---------------+--------------+--------+
| id | submission_id | key | value |
+----+---------------+--------------+--------+
| 1 | 10 | manufacturer | Apple |
| 2 | 10 | model | 5s |
| 3 | 10 | firstname | Paul |
| 4 | 15 | manufacturer | Apple |
| 5 | 15 | model | 5s |
| 6 | 15 | firstname | Paul |
| 7 | 20 | manufacturer | Apple |
| 8 | 20 | model | 5s |
| 9 | 20 | firstname | Andrew |
+----+---------------+--------------+--------+
From the data above you can see that the submissions with id of 10 and 15 both have the same values (just different submission id). This is basically because a user has submitted the same form twice and so is a duplicate.
Im trying to find a way to order these table where the any duplicate submissions appear together in order. Given the above table I am trying to build a query that gives me the result as below:
+---------------+
| submission_id |
+---------------+
| 10 |
| 15 |
| 20 |
+---------------+
So I want to check to see if a submission where the manufacturer, model and firstname keys have the same value. If it does then these get the submission id and place them adjacently in the result. In the actual table there are other keys, but I only want to match duplicates based on these 3 keys (manufacturer, model, firstname).
I’ve been going back and forth to the drawing board quite some time now and have tried looking for some possible solutions but cannot get something reliable.
That's not a key value table. It's usually called an Entity-Attribute-Value table/relation/pattern.
Looking at the problem, it would be trivial if the table were laid out in conventional 1st + 2nd Normal form - you just do a join on the values, group by those and take a count....
SELECT manufacturer, model, firstname, COUNT(DISTINCT submission_id)
FROM atable
GROUP BY manufacturer, model, firstname
HAVING COUNT(DISTINCT submission_id)>1;
Or a join....
SELECT a.manufacturer, a.model, a.firstname
, a.submission_id, b.submission_id
FROM atable a
JOIN atable b
ON a.manufacturer=b.manufacturer
AND a.model=b.model
AND a.firstname=b.firstname
WHERE a.submission_id<b.submission_id
;
Or using sorting and comparing adjacent rows....
SELECT *
FROM
(
SELECT #prev.submission_id AS prev_submission_id
, #prev.manufacturer AS prev_manufacturer
, #prev.model AS prev_model
, #prev.firstname AS pref_firstname
, a.submission_id
, a.manufacturer
, a.model
, set #prev.submission_id:=a.submission_id as currsid
, set #prev.manufacturer:=a.manufacturer as currman
, set #prev.model:=a.model as currmodel
, set #prev.firstname=a.forstname as currname
FROM atable
ORDER BY manufacturer, model, firstname, submission_id
)
WHERE prev_manufacturer=manufacturer
AND prev_model=model
AND prev_firstname=firstname
AND prev_submission_id<>submission_id;
So the solution is to simply make your data look like a normal relation....
SELECT ilv.values
, COUNT(ilv.submission_id)
, GROUP_CONCAT(ilv.submission_id)
FROM
(SELECT a.submission_id
, GROUP_CONCAT(CONCAT(a.key, '=',a.value)) AS values
FROM atable a
GROUP BY a.submission_id
) ilv
GROUP BY ilv.values
HAVING COUNT(ilv.submission_id)>1;
Hopefully the join and sequence based solutions should now be obvious.

Get user's primary email address mysql php best practices

I have a user table and a contact info table so that each user can have multiple phone numbers and multiple email addresses. Is there a standard way to set and retrieve their primary contact info?
"humans" table
ID | name
1 | John
2 | Joan
"human_contact" table
ID | contact_type | contact_info | user_id
1 | email | john#a.com | 1
2 | email | johnny#b.net | 1
"tickets" table
ID | human_id | event_date
1 | 1 | 2017-08-01
if John usually uses johnny#b.net, how do I mark that row as his favorite and retrieve that one for most queries?
SELECT *
FROM tickets
LEFT JOIN humans
ON tickets.human_id=humans.ID
LEFT JOIN human_contact
ON human_contact.human_id=humans.ID
WHERE tickets.ID='112'
You can use an extra coloumn named as fav which will have boolean values. This can help you in first finding whether he has any fav using a check where fav==true, then going on with that contact_info , or if the user doesnt have any favourites, then go with your usual query.
That is,
if( query( fav==1 for atleast 1 tuple )){
return tuple with fav==1;
else{
query ( usual query to get contact_info );
return query_result;
}
for more easier understanding.Hope this helps.

sql expert - select multiple values from multiple columns without the results repeat on itself

I am looking for a SQL that search in one table in few columns without the result jump twice,
first_name | last_name |
------------------------
george | klounie |
jimmi | parker |
rechard | klinton |
bill | klinton |
What I want to do is search for two keywords array(0=>"bill",1=>"klinton")
And I want to get just the bill klinton row.
I have tried to put my php code in a loop but then I get
1st result -> bill klinton
2nd result -> [0]rechard klinton [1] bill klinton
You can do that with MySQL LIKE
SELECT * FROM TABLENAME
WHERE first_name LIKE "%bill%"
AND last_name LIKE "%klinton%" ;

Compare a value from a CSV column in mysql with more checks

I need to have a query which has two parts.
I mean two where clause.
till now I have reached to the following, but it dosen't work properly.
SELECT * from items
where
FIND_IN_SET( '3', category_id )
AND postcode LIKE 'sw19%'
order by id
this query only runs the first part, i.e., the FIND_IN_SET() part. and just ignores the second part i.e., Postcode check...
I want to know is there a solution for this kind of query.
DETAILS
I want to compare the values from 2 columns:
1 column is a csv column , eg. 1,2,3,4,5
the other is postcode B17 SW19 etc
Table is like the following.
---+------+-------------+----------+-
id | item | category_id | postcode |
---+------+-------------+----------+-
1 | abc | 1,2,3,4 | SW19 |
---+------+-------------+----------+-
2 | def | 3,4,5 | NW6 |
---+------+-------------+----------+-
3 | xyz | 6,7,8,9 | SW19 |
---+------+-------------+----------+-
4 | ghi | 8,9,10,11 | SW19 |
---+------+-------------+----------+-
etc.
if I want to select an entry whose category_id contains '3' AND whose postcode starts from 'SW', what query will it be?
I just found out the solution which completely resolves my problem and though it would help someone in future.
Well, the query goes like this:
Select * from table_name where FIND_IN_SET('3', category_id) >0 AND postcode LIKE 'sw%'
Regards,
Shoaib.
:) Just simple query for this
SELECT * FROM tablename1 WHERE category_id LIKE '%,3,%' AND postcode LIKE 'SW%'

MYSQL INSERT SELECT problem

i have a little difficulty in understanding how to do some INSERT SELECT.
For instance i have two tables.
TABLE : users
id | name | gender
1 | John | m
2 | Mary | f
TABLE : website
fid | url | id
1 | www.desilva.biz | 2
2 | gidhelp.com | 4
Now let's say i want to add another query to the table website. I get two variables, lets say:
$user = John;
$site = "www.google.com";
i want to select the id of John from users table and insert it into website table in one statement.
How can i do it?
Assuming your variables are already escaped properly and are not subject to SQL injection:
INSERT
INTO website (url, fid)
SELECT $site, id
FROM users
WHERE name = $user