select only rows with unique combination of two columns - mysql

I have a SQL query that's fetching a result like:
[{"id":89,"sender_id":2,"reciever_id":1,"message":"no reply","deleted_at":null,"created_at":"2017-04-04 17:01:20","updated_at":"2017-04-04 17:01:20"},
{"id":88,"sender_id":1,"reciever_id":2,"message":"hiiiii","deleted_at":null,"created_at":"2017-04-04 16:59:47","updated_at":"2017-04-04 16:59:47"},
{"id":87,"sender_id":5,"reciever_id":1,"message":"hiiiii","deleted_at":null,"created_at":"2017-04-04 16:59:43","updated_at":"2017-04-04 16:59:43"},
{"id":86,"sender_id":1,"reciever_id":5,"message":"hiiii","deleted_at":null,"created_at":"2017-04-04 16:59:38","updated_at":"2017-04-04 16:59:38"},
{"id":85,"sender_id":1,"reciever_id":5,"message":"hiii vRUN\n","deleted_at":null,"created_at":"2017-04-04 16:10:51","updated_at":"2017-04-04 16:10:51"}]
But I want only unique combinations of sender_id and reciever_id. I need only 2 rows out of 5 because only 2 rows have unique combination. Like this:
[{"id":89,"sender_id":2,"reciever_id":1,"message":"no reply","deleted_at":null,"created_at":"2017-04-04 17:01:20","updated_at":"2017-04-04 17:01:20"},
{"id":87,"sender_id":5,"reciever_id":1,"message":"hiiiii","deleted_at":null,"created_at":"2017-04-04 16:59:43","updated_at":"2017-04-04 16:59:43"},
How can I achieve that?

add a GROUP BY like this
SELECT *
FROM yourTable
GROUP BY SUBSTRING_INDEX(SUBSTRING_INDEX( ,',',3),':',-1)
sample
mysql> SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('[{"id":89,"sender_id":2,"reciever_id":1,"message":"no reply","deleted_at":null,"created_at":"2017-04-04 17:01:20","updated_at":"2017-04-04 17:01:20"},' ,',',3),':',-1) as result;
+--------+
| result |
+--------+
| 1 |
+--------+
1 row in set (0,00 sec)
mysql>

Related

SQL find rows in table based on search results in another table

I'm looking for a way to search a table values from the results of a query on another table :
SELECT entry_id FROM FEEDENTRYSTATUSES WHERE starred > 0 ;
+----------+
| entry_id |
+----------+
| 1036 |
| 1059 |
+----------+
2 rows in set (0.00 sec)
SELECT url from FEEDENTRIES WHERE id = 1036 ;
+---------------------+
| url |
+---------------------+
| https://google.com/ |
+---------------------+
1 row in set (0.00 sec)
So I can get a list of IDs from the FEEDENTRYSTATUSES table.
I can retrieve value from second table manually by giving the value 1036.
But I would like to search in table FEEDENTRIES from values returned by first SELECT.
Is here a way to do so ?
Any help very much appreciated.
Thanks a lot
You can use IN operator and subquery to achieve that:
SELECT url from FEEDENTRIES
WHERE id IN (SELECT entry_id FROM FEEDENTRYSTATUSES WHERE starred > 0);
Or join the tables and filter the data that you need:
SELECT fe.url from FEEDENTRIES fe
INNER JOIN FEEDENTRYSTATUSES fes ON fe.id = fes.entry_id
WHERE fes.starred > 0;

How to extract the rows that contain only 1 "=" by using REGEXP in MySQL?

Suppose I have a table named "t1" which contains a column named "ID" which has the following records
abcde=1=2
qwert=3
hhhhj=9
zxcv=5=8
How can I extract the records that contain only 1 "=" sign by using REGEXP in MySQL?
I've tried
SELECT * FROM t1 WHERE ID REGEXP '\\w*=\\w*=\\w*'; -- returns no records
SELECT * FROM t1 WHERE ID REGEXP '\\w*=\\w*'; -- returns all 4 records
I expected the first query to return the records which contains 2 "=", and the second query to return the records which contains only 1 "=".
What's wrong with my queries?
A pretty simple solution without REGEXP would be
select * from table
where
length(ID) - length(replace(ID,'=','')) = 1 ;
Some test cases
mysql> select length('qwert=3') - length(replace('qwert=3','=','')) as diff;
+------+
| diff |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
mysql> select length('zxcv=5=8') - length(replace('zxcv=5=8','=','')) as diff;
+------+
| diff |
+------+
| 2 |
+------+
1 row in set (0.00 sec)
SELECT * FROM t1 WHERE ID REGEXP '^[^=]*=[^=]*$';
Guess this should do it.See fiddle http://www.sqlfiddle.com/#!9/b2ead/2/0

MySQL Escape Character Issue

While I was trying to solve This Question. I created the dummy records in a table
create table mytable(data CHAR(30));
INSERT INTO mytable VALUES('d\\one'),('d\\two'),('d\\three');
SELECT * FROM mytable;
+---------+
| data |
+---------+
| d\one |
| d\two |
| d\three |
+---------+
3 rows in set (0.00 sec)
Now when i am selecting records, I am getting no result, I have tried many combination with like but no luck.
Ex :
SELECT * FROM mytable WHERE data LIKE "d\\%";
Empty set (0.00 sec)
SELECT * FROM mytable WHERE data LIKE 'd\\%';
Empty set (0.00 sec)
Use triple slash:
SELECT * FROM mytable WHERE data LIKE "d\\\%"
Or use INSTR() instead
SELECT * FROM mytable WHERE instr(data, 'd\\') = 1

Using GROUP_CONCAT output for subquery

I'm running into a problem, I have the following line in my query
CONCAT('',
(SELECT GROUP_CONCAT(DISTINCT trips_loads_rel.load_id,'') AS x
FROM `trips_loads_rel` WHERE trips_loads_rel.trip_id = trips.Id)
) AS loads
It shows something like 8,10,27 (ie, numeric IDs), some Ids from trips_loads_rel table. It works ok. However, how can I use that output to pull matching records from other table? I mean, the line shows me all ids ok, but I need to query other table with these to pull related records. Actually I don't need these IDs, I need their matching records...
try this:
SELECT * FROM <other_table> WHERE <other_table>.load_id IN(CONCAT('',
(SELECT GROUP_CONCAT(DISTINCT trips_loads_rel.load_id,'') AS x
FROM `trips_loads_rel` WHERE trips_loads_rel.trip_id = trips.Id)
) AS loads)
It looks like it's a part of a query, not an entire one, so hard to show exact syntax, but if you want to use the values to find other rows, just don't group concat them to begin with.
Instead just use them directly doing something like;
SELECT * FROM `other_table` WHERE `other_table`.`load_id` IN
(SELECT `load_id` FROM `trips_loads_rel` WHERE `trip_id` = `trips`.`Id`)
You can use FIND_IN_SET(col, 'csv as string') function to get the desired results.
Example:
mysql> select find_in_set( 2, '11,12,13,14,15,2' );
+--------------------------------------+
| find_in_set( 2, '11,12,13,14,15,2' ) |
+--------------------------------------+
| 6 |
+--------------------------------------+
1 row in set (0.00 sec)
mysql> select find_in_set( 2, '2,11,12,13,14,15,2' );
+----------------------------------------+
| find_in_set( 2, '2,11,12,13,14,15,2' ) |
+----------------------------------------+
| 1 |
+----------------------------------------+
1 row in set (0.00 sec)
mysql> Select FIND_IN_SET( 6, '1,12,3,14,5,16,7,18,9,0,2,13,4,15,6,17,8' );
+--------------------------------------------------------------+
| FIND_IN_SET( 6, '1,12,3,14,5,16,7,18,9,0,2,13,4,15,6,17,8' ) |
+--------------------------------------------------------------+
| 15 |
+--------------------------------------------------------------+
1 row in set (0.00 sec)
mysql>
For your query you can pass the concatenated output '8,10,27' to compare with other_table's column.
Select find_in_set( other_table.col_name, '8,10,27' );
Refer To:
MySQL String Functions: FIND_IN_SET()

Populating a table from query results (mysql)

I would like to fill a table with the results of a query on existing table. How can I do that?
(You don't need to match the table schemas)
INSERT tbl_name (col1, col2)
SELECT value1, value2
FROM othertable
See the reference for INSERT ... SELECT Syntax
insert into table_name ...
select * from table_name where ....
The target table and the source query must match in number of columns and datatypes
See this link
You can even create tables this way, though there the column names must match, or the select results are put in automatically added columns:
mysql> create table foo ( id int primary key auto_increment, bar datetime )
-> select now() as bar, now() as baz from dual;
Query OK, 1 row affected, 1 warning (0.06 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> select * from foo;
+----+---------------------+---------------------+
| id | bar | baz |
+----+---------------------+---------------------+
| 1 | 2009-03-10 17:01:35 | 2009-03-10 17:01:35 |
+----+---------------------+---------------------+
1 row in set (0.00 sec)