INNER JOIN DISTINCT with MySQL - mysql

I have a mysql problem. I have two tables like this that I need to join together.
table:
id otherid2
1 | 1
2 | 1
3 | 2
4 | 2
table2:
otherid otherid2
1 | 1
2 | 1
3 | 2
4 | 2
I'm using:
SELECT id,otherid FROM table INNER JOIN table2 ON table.otherid2=table2.otherid2
This gives me:
id otherid
1 | 1
1 | 2
2 | 1
2 | 2
3 | 3
3 | 4
4 | 3
4 | 4
As you can see I get duplicates of id as there is otherid2s that is not unique in table2. What I need is to INNER JOIN DISTINCT in some way, I only want the result to be as below. Not duplicates.
This is what I want:
id otherid
1 | 1
2 | 1
3 | 3
4 | 3
Can I do this in an easy way?

If you want the row with the lowest id in table2, this should probably do it
SELECT id, min(otherid)
FROM table
INNER JOIN table2
ON table.otherid2=table2.otherid2
GROUP BY id

In your comment you wanted the lowest, then I'd suggest a group by and a min aggregator
SELECT id, MIN(otherid) AS otherid ... GROUP BY id

Related

What is the maximum number of rows from a left join

What is the maximum number of rows from a left join from the below query?
select t1.tribe_name, t2.*
from tribe_master as t1
left join demography as t2
on t1.stc_code=t2.stc_code
In the above query table tribe_master has total 868 records
and table demography has 16924 records,
but the output of the query shows 14,899 records.
How is this possible.
Please explain.
Let's say we have two tables, A & B and both tables have each id of 1 & 2 like below. When you use A.id=B.id you'll get two matches:
Ex1:
SELECT * FROM
(SELECT 1 id UNION SELECT 2) A LEFT JOIN
(SELECT 1 id UNION SELECT 2) B ON A.id=B.id;
+----+----+
| id | id |
+----+----+
| 1 | 1 |
| 2 | 2 |
+----+----+
*2 row(s);
If table A only have id 1 and table B have id 1 & 2, result will show only 1 match:
Ex2:
SELECT * FROM
(SELECT 1 id) A LEFT JOIN
(SELECT 1 id UNION SELECT 2) B ON A.id=B.id;
+----+----+
| id | id |
+----+----+
| 1 | 1 |
+----+----+
*1 row(s);
If table A have id 1 & 2 and table B only have id 1, you'll get 2 rows of result regardless of how many matching id there is. However in the id section from table B, you'll only get data for whatever matches and get NULL for non-matching data.
Ex3:
SELECT * FROM
(SELECT 1 id UNION SELECT 2) A LEFT JOIN
(SELECT 1 id) B ON A.id=B.id;
+----+---------+
| id | id |
+----+---------+
| 1 | 1 |
| 2 | (NULL) |
+----+---------+
*2 row(s);
When you have id 1 & 2 in table A and duplicate id 2 in table B, you'll get 3 rows since id 2 from table A matches with two rows if id 2 data in table B. And of course, NULL for non-matching data.
Ex4:
SELECT * FROM
(SELECT 1 id UNION SELECT 2) A LEFT JOIN
(SELECT 2 id UNION ALL SELECT 2) B ON A.id=B.id;
+----+---------+
| id | id |
+----+---------+
| 1 | (NULL) |
| 2 | 2 |
| 2 | 2 |
+----+---------+
*3 row(s);
Then the last test here showing both tables have two rows of duplicate id 1 which resulted in 4 total rows because each of the id 1 row in table A recognizes that there are two matching id in table B
Ex5:
SELECT * FROM
(SELECT 1 id UNION ALL SELECT 1) A LEFT JOIN
(SELECT 1 id UNION ALL SELECT 1) B ON A.id=B.id;
+----+----+
| id | id |
+----+----+
| 1 | 1 |
| 1 | 1 |
| 1 | 1 |
| 1 | 1 |
+----+----+
*4 row(s);
Yours probably have a few data in table tribe_master that don't exists in table demography and some repeated stc_code values in the demography. Something like Ex4 example above.

Check multiple columns for duplicate and list all records

I have a table with columns ID, Content and Day. I am trying to find all rows that have duplicate Content and Day values and display all rows
SELECT ID,Content, `Day`, Count(*)
FROM table
GROUP BY Content,`Day`
HAVING COUNT(*) > 1
The current code will return a list of duplicate Content and 'Day' values for instance:
ID|Content|Day
1 | a | 1
2 | a | 1
3 | a | 1
4 | b | 2
5 | b | 2
6 | c | 3
7 | c | 4
Will result in:
ID|Content|Day|Count
1 | a | 1 | 3
4 | b | 2 | 2
But I want to display all the unique IDs as well;
ID|Content|Day
1 | a | 1
2 | a | 1
3 | a | 1
4 | b | 2
5 | b | 2
Just make a Sub-Query
select *
from table
where `day` in
(
SELECT ID
FROM table
GROUP BY Content,`Day`
HAVING COUNT(*) > 1
) A
Use that query as a subquery to join against the table again:-
SELECT table.ID, table.Content, table.`Day`
FROM table
INNER JOIN
(
SELECT Content, `Day`, Count(*)
FROM table
GROUP BY Content,`Day`
HAVING COUNT(*) > 1
) sub0
ON sub0.Content = table.Content
AND sub0.`Day` = table.`Day`

Get other user_ids which have same mid

I want to search user_id of 1 in table below and get other user_ids related to same mid ( in this case mid of 1 & 3)
mid | user_id
1 1
1 2
1 3
2 2
2 3
2 5
3 1
3 5
3 2
The result must be :
mid | user_id
1 1
1 2
1 3
3 1
3 5
3 2
How is it done with MySQL query ?
Assuming I understood correctly, you want to first find all mid values that have a user_id value of 1, then get all user_id values from all those previously gotten mid values.
SELECT mid, user_id from table
where mid IN (SELECT mid FROM table WHERE user_id = 1)
Assuming that you want to get all rows for those mid that matches a user_id this should do what you want:
select * from your_table t1
where exists (
select 1 from your_table t2
where user_id = 1
and t1.mid = t2.mid
)
Sample SQL Fiddle
Result given your sample data:
| MID | USER_ID |
|-----|---------|
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 3 | 1 |
| 3 | 5 |
| 3 | 2 |

Retrieve the number on subscriber

I've two tables, Table1(News) and Table2(Subscribers).
Table1: id, news_title
Table2: id, news_id, user_id
Table1
id | news_title
--------------
1 | News 1
2 | News 2
3 | news 3
Table2
id | news_title_id | user_id
----------------------------
1 | 1 | 1
2 | 1 | 2
3 | 2 | 3
I need a query result like this.
news_title | subscribers
------------------------
News 1 | 2
News 2 | 1
News 3 | 0
Any help?
A simple aggregate COUNT(*) with a LEFT JOIN will do the job here. LEFT JOIN and COUNT(*) (rather than COUNT(user_id)) are used to be sure titles with zero subscribers still return a row.
SELECT
news_title,
COUNT(Table2.*) AS subscribers
FROM Table1 LEFT JOIN Table2 ON Table1.id = Table2.news_title_id
GROUP BY news.title

how to select 3 random items of each category?

I need some help writing a select query basically I have the table structured as below:
cat_prod
----------
cid | pid
----------
1 | 1
2 | 2
3 | 3
4 | 4
5 | 5
1 | 2
2 | 3
3 | 4
4 | 5
5 | 1
1 | 3
2 | 4
3 | 5
4 | 1
5 | 2
Now I would like to select at least 3 random pid's of each cid where it exists or the maximum pid's if less than 3, how would i do that in one query? Baring in mind I would like the query to be as efficent as possible and that the table data is likely to grow considerablly.
Thanks
Although some changes might be needed, the following query is almost appropriate:
select C.cid, C.pid
from cat_prod C
where C.pid in (select c1.pid from cat_prod c1 order by (pid) limit 3);