Retrieve the number on subscriber - mysql

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

Related

I am not sure what is wrong with my MySQL GROUP_CONCAT query...can you solve it for me please?

I have a MySQL problem which i can't figure out the solution.
I have 2 tables
Table 1-[Book] table
book id | categories | title |
1 | 1,3,5 | Book 1 |
2 | 2,4 | Book 2 |
3 | 1,4 | Book 3 |
Table 2-[Category] table
category id | category name
1 | Technology
2 | Accounting
3 | Science
4 | Math
5 | Chemistry
I need the result to show up like this
RESULT
book id | categories | title | category name
1 | 1,3,5 | Book 1 | Technology,Science,Chemistry
2 | 2,4 | Book 2 | Accounting,Math
3 | 1,4 | Book 3 | Technology,Math
I tried the below query but i'm not sure what's wrong with it.
SELECT DISTINCT t1.*,(SELECT GROUP_CONCAT(t2.categoryName) FROM `tbl_category` t2 WHERE t2.id IN (t1.categories)) catColumn FROM tbl_books t1 ORDER BY t1.id DESC
If I execute the below query, it is returning the correct values that I need:
SELECT GROUP_CONCAT(categoryName) FROM `tbl_category` t2 WHERE t2.id IN (1,3,5)
RESULT:
Technology,Science,Chemistry
Your first effort should go into fixing your schema. You should have a separate table to store the book/category relations, with each tuple in a separate table row. Storing delimited lists in a database table is bad design, and should be always be avoided: see this famous SO question for more details.
For your current set up though, I would recommend a correlated subquery with find_in_set():
select
b.*,
(
select group_concat(c.category_name)
from category c
where find_in_set(c.id, b.categories)
) category_names
from book b
To echo others, the first thing I would do is make a minor change to your table structure and de-couple books from categories, like this:
TABLE BOOK
book id | title |
1 | Book 1 |
2 | Book 2 |
3 | Book 3 |
TABLE CATEGORY
category id | category name
1 | Technology
2 | Accounting
3 | Science
4 | Math
5 | Chemistry
TABLE BOOK_CATEGORY
id | book_id | category_id
1 | 1 | 1
2 | 1 | 3
3 | 1 | 5
4 | 2 | 2
5 | 2 | 4
6 | 3 | 1
7 | 3 | 4
Finally, to achieve your desired result, execute the following query:
SELECT
b.book_id,
group_concat(bc.category_id order by bc.category_id) AS category_id,
b.title,
group_concat(c.category_name) AS category_name
FROM
book b
INNER JOIN
book_category bc ON b.book_id = bc.book_id
INNER JOIN
category c ON c.category_id = bc.category_id
GROUP BY
book_id;

SQL: join 2 table and change id to username

i have table like this:
table1:
id | item_name | entered_by | modify_by
1 | banana | 2 | 1
2 | apple | 4 | 3
3 | orance | 1 | 1
4 | pineapple | 5 | 3
5 | grape | 6 | 1
table2:
id | username
1 | admin
2 | jack
3 | danny
4 | dummy
5 | john
6 | peter
how do i join these 2 table for table1's entered_by and modify_by is replaced by their username with id correspondingly on table2.
thanks
Try this out:
SELECT t1.id, t1.item_name,
t2enteredBy.username enteredBy,
t2modifyBy.username modifyBy
FROM table1 t1
JOIN table2 t2enteredBy ON t1.entered_by = t2enteredBy.id
JOIN table2 t2modifyBy ON t1.modify_by = t2modifyBy.id
Fiddle here.
In short, you need a join per each of those fields. That's why there is a double join on table2.
SELECT tmp.id, item_name, tmp.username as entered, b.username as modify
FROM (SELECT t.id, item_name, username, modify_by
FROM table1 t
INNER JOIN table2 a
ON t.entered_by=a.id
)tmp
INNER JOIN table2 b ON tmp.modify_by=b.id

How to make cross select in one table?

Consider this table:
I need to make a SQL query which returns highlighted rows. In other words: rows which are linked to each other by idContactTo.
Example:
1 has contact to 2, 2 has contact to 1 - they are linked and should be in result table. But even 1 has contact to 3 it doesn't mean that 3 has contact to 1 - they aren't linked.
You can do it via INNER JOIN,
SELECT a.*
FROM tableName a
INNER JOIN tableName b
ON a.idContantOwner = b.idContactTo AND
b.idContantOwner = a.idContactTo
SQLFiddle Demo
Another way to do it
SELECT t.*
FROM
(
SELECT MiN(id) min_id, MAX(id) max_id
FROM Table1
GROUP BY LEAST(idContactOwner, idContactTo),
GREATEST(idContactOwner, idContactTo)
HAVING COUNT(*) = 2
) q JOIN Table1 t
ON t.id IN(q.min_id, q.max_id)
Output:
| ID | IDCONTACTOWNER | IDCONTACTTO |
|----|----------------|-------------|
| 1 | 1 | 2 |
| 2 | 2 | 1 |
| 4 | 3 | 4 |
| 5 | 4 | 3 |
Here is SQLFiddle demo

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