What is the maximum number of rows from a left join - mysql

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.

Related

Select three tables and count

I have three tables, I need to select email and count the relation between table A and table B, for example:
Table A:
ID | email
1 | test#test
2 | test2#test
3 | test3#test
Table B:
UID | username
11 | James
22 | Gabriel
33 | Jonas
Table C: (Relation between A and B)
ID | email_id | username_id
1 | 1 | 11
2 | 1 | 22
3 | 2 | 33
Expect Result:
Email | Totalrelation
test#test | 2
test2#test | 1
I tried:
select tableA.email,
COUNT(distinct tableC.email_id) AS total from tableA as tableA, tableC as tableC GROUP BY tableC.email_id
But it didnt work, I got total wrong. How can I do it?
Join the tables, group the data and count the number for each group
select a.email, count(c.id) as cnt
from tableA a
left join tableC c on c.email_id = a.id
group by a.email

Get records from one table and a corresponding table

I have two tables:
orders
poid | user | pid | payment_id
1 | 1 | 1 | abc123
2 | 2 | 2 | def345
orders_addon
poaid | user | poid | pid
1 | 1 | 1 | 3
2 | 1 | 1 | 5
One represents orders, the second one represent addons a user can add to his order.
There is always a row in orders and it can occur that there is no matching orders_addon for an order.
I'm looking for a query that returns matching rows from orders and orders_addon if there are matching ones.
SELECT user,pid FROM ... WHERE payment_id = 'abc123'
Should return
user | pid
1 | 1
1 | 3
1 | 5
And the same query should only return results from the orders table if there is no matching record in the orders_addon table.
SELECT user,pid FROM ... WHERE payment_id = 'def345'
user | pid
2 | 2
I reckon this could be done using UNION but then I wouldn't be able to match the tables and it would become a problem since the orders_addon table doesn't have a payment_id
Use LEFT JOIN WITH IF STATMENT
mysql> ( SELECT u.user,IFNULL(ua.pid ,u.pid) as pid
FROM orders u
inner JOIN orders_addon ua on ua.poid=u.poid
WHERE u.payment_id = 'abc123'
)
union all
( SELECT u.user,u.pid
from orders u
where u.payment_id = 'def345'
);
+------+------+
| user | pid |
+------+------+
| 1 | 3 |
| 1 | 5 |
| 2 | 2 |
+------+------+
3 rows in set (0.00 sec)
mysql> ( SELECT u.user,IFNULL(ua.pid ,u.pid) as pid
FROM orders u
inner JOIN orders_addon ua on ua.poid=u.poid
WHERE u.payment_id = 'def345'
)
union all
( SELECT u.user,u.pid
from orders u
where u.payment_id = 'def345'
);
+------+------+
| user | pid |
+------+------+
| 2 | 2 |
+------+------+
1 row in set (0.00 sec)

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`

Count multiple columns with same WHERE condition

I have a users table with columns: user_id, teacher_id1, teacher_id2, teacher_id3
and
teachers table with id
Each user can have the same id's for teacher_id1, teacher_id2, teacher_id3
I would like to count how many users have same teacher.
User table
+----------------------------------------+
| user_Id teacher_id1 teacher_id2 teacher_id3 |
+----------------------------------------+
| 1 1 1 1 |
| 2 2 1 3 |
| 3 2 3 3 |
| 4 2 2 2 |
+----------------------------------------+
Teacher table
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
Count for $id1 is: 2
Count for $id2 is: 3
Count for $id3 is: 2
I tried something like this, but it is not correct!
SELECT COUNT(*) FROM users WHERE concat_ws('',teacher_id1 OR teacher_id2
OR teacher_id3) like '{$id}' ";
You have data in three different columns. You need to combine it into one column, to get the distinct counts that you want. For this, you can use union all. Then the count is simply count(distinct):
select teacher_id, COUNT(distinct USER_ID)
from ((select user_id, teacher_id1 as teacher_id
from t
) union all
(select user_id, teacher_id2
from t
) union all
(select user_id, teacher_id3
from t
)
) s
group by teacher_id;
Try this query
select b.id, count(*)
from
tbl1 a
inner join
tbl2 b
on b.id = teacher_id1 or b.id = teacher_id2 or b.id = teacher_id3
group by b.id
SQL FIDDLE:
| ID | COUNT(*) |
-----------------
| 1 | 2 |
| 2 | 3 |
| 3 | 2 |

INNER JOIN DISTINCT with 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