Select count of users over two tables - mysql

I want to count the occurrence of the same user id in two tables.
The jos_findme table has all the users in it. The other two have as well the column "user id".
But I want the overall count in the two tables. I tried this but it does not work?
SELECT
c.user_id, count(c.user_id) AS counter
FROM
jos_findme as c
LEFT JOIN
jos_findme_bestof as b ON b.user_id = c.user_id
LEFT JOIN
jos_findme_pair as p ON p.user_id = c.user_id
WHERE
c.user_id > 0
GROUP BY c.user_id
ORDER BY counter DESC
LIMIT 10
ALL tables have the column "user_id". I just want to count them in the tables "jos_findme_bestof" and "jos_findme_pair"

Correlated subqueries could be useful here:
SELECT c.user_id,
(SELECT Count(*)
FROM jos_findme_bestof b
WHERE b.user_id = c.user_id),
(SELECT Count(*)
FROM jos_findme_pair p
WHERE p.user_id = c.user_id)
FROM jos_findme c

Try this
SELECT c.user_id,
Users1 = (SELECT COUNT(*) FROM jos_findme_bestof b WHERE b.user_id = c.user_id),
Users2 = (SELECT COUNT(*) FROM jos_findme_pair p WHERE p.user_id = c.user_id),
TotalUser = (SELECT COUNT(*) FROM jos_findme_bestof b WHERE b.user_id = c.user_id)
+
(SELECT COUNT(*) FROM jos_findme_pair p WHERE p.user_id= c.user_id)
FROM
jos_findme c
Here,
Users1 will return all users from jos_findme_bestof
Users2 will return all users from jos_findme_pair
TotalUser will be count of both the tables
Hope it would helps you!
Thanks.

Try this:
SELECT c.user_id, (IFNULL(b.bCount, 0) + IFNULL(p.pCount, 0)) AS counter
FROM jos_findme AS c
LEFT JOIN (SELECT b.user_id, COUNT(1) bCount
FROM jos_findme_bestof b
GROUP BY b.user_id
) AS b ON b.user_id = c.user_id
LEFT JOIN (SELECT p.user_id, COUNT(1) pCount
FROM jos_findme_pair p
GROUP BY p.user_id
) AS p ON p.user_id = c.user_id
WHERE c.user_id > 0
GROUP BY c.user_id
ORDER BY counter DESC
LIMIT 10

I think you can do something like this:
SELECT AA.user_id, AA.Acounter + BB.Bcounter
from (SELECT a.user_id, count(a.user_id) AS Acounter
FROM jos_findme_bestof as a
GROUP BY a.user_id) as AA
Join
(SELECT b.user_id, count(b.user_id) AS Bcounter
FROM jos_findme_pair as b
GROUP BY b.user_id) as BB
on AA.user_id = BB.user_id
if you wants all the ids (meaning if there are id's in jos_findme_pair that are not in jos_findme_bestof) - use FULL OUTER JOIN

Related

Get Value from INNER JOIN 3 table with LASTEST RECORD from each table

I get problem to get value from some of tables. You can see picture below, I wanna get row what I block with red color.
I try with code below
SELECT p.id,
p.email,
p.name,
p.lastname,
p.gender,
ex.startwork,
ex.endwork,
e.degree,
e.majority,
j.division
FROM job_jobseeker AS p
INNER JOIN job_experience AS ex
ON p.email = (SELECT ex.email
FROM job_experience
ORDER BY ex.id DESC
LIMIT 1)
INNER JOIN job_education AS e
ON p.email = (SELECT e.email
FROM job_education
ORDER BY ex.id DESC
LIMIT 1)
INNER JOIN job_applying AS j
ON p.email = (SELECT j.email
FROM job_applying
ORDER BY ex.id DESC
LIMIT 1)
You need correlated sub-queries.
Find the latest id for each email in all the three tables
SELECT startwork,
endwork,
email
FROM job_experience a
WHERE a.id = (SELECT Max(b.id)
FROM job_experience b
WHERE a.email = b.email)
The above query will find the latest id for each email in job_experience table. Do the same for other two tables as well, then join the result with job_jobseeker table to get the result.
SELECT p.id,
p.email,
p.name,
p.lastname,
p.gender,
ex.startwork,
ex.endwork,
e.degree,
e.majority,
j.division
FROM job_jobseeker AS p
INNER JOIN (SELECT startwork,
endwork,
email
FROM job_experience a
WHERE a.id = (SELECT Max(b.id) FROM job_experience b
WHERE a.email = b.email)) AS ex
ON p.email = ex.email
INNER JOIN (SELECT email, //Just called column without initialize
degree,
majority
FROM job_education a
WHERE a.id = (SELECT Max(b.id) FROM job_education b
WHERE a.email = b.email)) AS e
ON p.email = e.email
INNER JOIN (SELECT email, //Just called column without initialize
division
FROM job_applying a
WHERE a.id = (SELECT Max(b.id) FROM job_applying b
WHERE a.email = b.email)) AS j
ON p.email = j.email

mysql join with multiple tables and count query

I have total 6 tables in which different info has been saved
Now i need a result in which get count from 5 tables and select all info from main table but if record does not exist than it must be need to return 0 instead of no row found that's the problem here
I have tried below query but didn't get success
SELECT
u.*,
COUNT(DISTINCT c.id) as comments,
COUNT(DISTINCT d.id) as dislikes,
COUNT(DISTINCT l.id) as likes,
COUNT(DISTINCT s.id) as shares,
COUNT(DISTINCT t.id) as tags
FROM
job_details as u
JOIN job_comments as c ON u.id = c.job_id
JOIN job_dislike as d ON u.id = d.job_id
JOIN job_like as l ON u.id = l.job_id
JOIN job_share as s ON u.id = s.job_id
JOIN job_tags as t ON u.id = t.job_id
WHERE
u.id = c.job_id AND
u.id = d.job_id AND
u.id = l.job_id AND
u.id = s.job_id AND
u.id = t.job_id
GROUP BY
u.id
This query is executed, but didn't get exact result.
I don't quite understand why.
I was hoping somebody here could help me out?
Thanks!
You probably didn't get the exact result because some tables may be missing values.
Although you can solve this problem with a LEFT JOIN, the safer solution is to pre-aggregate the data:
SELECT u.*, c.comments, d.dislikes, l.likes, s.shares, t.tags
FROM job_details as u LEFT JOIN
(select c.job_id, count(*) as comments from job_comments group by c.job_id
) c
ON u.id = c.job_id LEFT JOIN
(select d.job_id, count(*) as dislikes from job_dislike d group by d.job_id
) d
ON u.id = d.job_id LEFT JOIN
(select l.job_id, count(*) as likes from job_like l group by l.job_id
) l
ON u.id = l.job_id LEFT JOIN
(select s.job_id, count(*) as shares from job_share s group by s.job_id
) s
ON u.id = s.job_id LEFT JOIN
(select t.job_id, count(*) as tags from job_tags t group by t.job_id
) t
ON u.id = t.job_id;
Why is this better? Consider an id that has 5 comments, likes, dislikes, shares and tags. The JOIN approach produces an intermediate result with 5*5*5*5*5 = 3,125 intermediate rows. Things can really get out of hand for popular ids.
Use LEFT JOIN instead of JOIN. and you don't need WHERE clause since you have joined those tables. And, use IFNULL function to return 0 for null values. You need to modify you query like this :
SELECT u.id,
IFNULL(COUNT(DISTINCT c.id),0) as comments,
IFNULL(COUNT(DISTINCT d.id),0) as dislikes,
IFNULL(COUNT(DISTINCT l.id),0) as likes,
IFNULL(COUNT(DISTINCT s.id),0) as shares,
IFNULL(COUNT(DISTINCT t.id),0) as tags
FROM job_details as u
LEFT JOIN job_comments as c ON u.id = c.job_id
LEFT JOIN job_dislike as d ON u.id = d.job_id
LEFT JOIN job_like as l ON u.id = l.job_id
LEFT JOIN job_share as s ON u.id = s.job_id
LEFT JOIN job_tags as t ON u.id = t.job_id
GROUP BY u.id

Sum of two tables with subqueries

I have the query
SELECT c.user_id,
(SELECT COUNT(*) FROM jos_findme_bestof b WHERE b.user_id = c.user_id) as bCount,
(SELECT COUNT(*) FROM jos_findme_pair p WHERE p.user_id = c.user_id) as pCount,
(SELECT COUNT(*) FROM jos_findme_style s WHERE s.user_id = c.user_id) as sCount,
FROM jos_findme c
how can I make a column with: bCount + pCount + sCount?
Thanks
If you want to add the column in your query:
SELECT *,(bCount+pCount+sCount) as sumCount FROM(
SELECT c.user_id,
(SELECT COUNT(*) FROM jos_findme_bestof b WHERE b.user_id = c.user_id) as bCount,
(SELECT COUNT(*) FROM jos_findme_pair p WHERE p.user_id = c.user_id) as pCount,
(SELECT COUNT(*) FROM jos_findme_style s WHERE s.user_id = c.user_id) as sCount,
FROM jos_findme c)
Try this
SELECT SUM(t.bCount+t.pCount+t.sCount) As TotalCount , t.user_id
FROM (
SELECT c.user_id as user_id,
(SELECT COUNT(*) FROM jos_findme_bestof b WHERE b.user_id = c.user_id) as bCount,
(SELECT COUNT(*) FROM jos_findme_pair p WHERE p.user_id = c.user_id) as pCount,
(SELECT COUNT(*) FROM jos_findme_style s WHERE s.user_id = c.user_id) as sCount
FROM jos_findme c ) t ;
Try this:
SELECT c.user_id,
(IFNULL(b.bCount, 0) + IFNULL(p.pCount, 0) + IFNULL(s.sCount, 0)) AS totalCount
FROM jos_findme c
LEFT JOIN (SELECT b.user_id, COUNT(1) bCount
FROM jos_findme_bestof b
GROUP BY b.user_id
) AS b ON b.user_id = c.user_id
LEFT JOIN (SELECT p.user_id, COUNT(1) pCount
FROM jos_findme_pair p
GROUP BY p.user_id
) AS p ON p.user_id = c.user_id
LEFT JOIN (SELECT s.user_id, COUNT(1) sCount
FROM jos_findme_style s
GROUP BY s.user_id
) AS s ON s.user_id = c.user_id
You can try this
SELECT c.user_id, sum(b.count(*)+p.count(*)+s.count(*)) as totalcount
from jos_findme c
join jos_findme_bestof b
on b.user_id = c.user_id
join jos_findme_pair p
on p.user_id = c.user_id
join jos_findme_style s
on s.user_id = c.user_id

mysql query - count words in common between users

I've a very nice query that selects friends of the current user. user_id = 2 in the example. His friend is user_id = 4.
I want the same query to fetch the number of words user_id 2 has with selected friends. In this case they have word = love, and this is also word they both have, so I want in_common row to say = 1.
Is it possible without changing too much current query?
Should I start from scratch?
SQL FIDDLE
Assuming that both users would have an entry for 'love' in the words_en table then something like this maybe:-
SELECT b.name_surname,
b.avatar,
b.friend_words,
(b.friend_msg_id) AS friend_msg_id,
words_common.words_in_common,
COUNT(m.id) AS unread_msg
FROM
(
SELECT a.name_surname as name_surname,
a.avatar as avatar,
GROUP_CONCAT(DISTINCT w.word ORDER BY w.word ASC) AS friend_words,
(a.friend_id) AS friend_msg_id
FROM
(
SELECT f1.asked_user_id AS friend_id,
f1.created,
u.name_surname,
u.avatar
FROM friends AS f1
INNER JOIN friends AS f2
ON f1.asked_user_id = f2.asker_user_id
AND f1.asker_user_id = f2.asked_user_id
INNER JOIN users AS u ON f1.asked_user_id = u.id
WHERE f1.status = 1 AND f2.status = 1
AND f1.asker_user_id = 2
) a
LEFT JOIN connections c ON c.user_id = a.friend_id
AND c.invisible <> 1 AND c.deleted <> 1
LEFT JOIN words_en w ON c.word_id = w.id
GROUP BY 1
) b
LEFT JOIN messages m ON m.to_user_id = 2
AND m.from_user_id = b.friend_msg_id
AND m.seen = 0
LEFT OUTER JOIN
(
SELECT b.user_id AS friend_id, GROUP_CONCAT(a.word) AS words_in_common
FROM words_en a
INNER JOIN words_en b
ON a.word = b.word
WHERE a.user_id = 2
GROUP BY b.user_id
) words_common
ON b.friend_msg_id = words_common.friend_id
GROUP BY b.name_surname, b.avatar, b.friend_words, b.friend_msg_id
ORDER BY unread_msg DESC
EDIT - modification to use connections table to find common words:-
SELECT b.name_surname,
b.avatar,
b.friend_words,
(b.friend_msg_id) AS friend_msg_id,
words_common.words_in_common,
COUNT(m.id) AS unread_msg
FROM
(
SELECT a.name_surname as name_surname,
a.avatar as avatar,
GROUP_CONCAT(DISTINCT w.word ORDER BY w.word ASC) AS friend_words,
(a.friend_id) AS friend_msg_id
FROM
(
SELECT f1.asked_user_id AS friend_id,
f1.created,
u.name_surname,
u.avatar
FROM friends AS f1
INNER JOIN friends AS f2
ON f1.asked_user_id = f2.asker_user_id
AND f1.asker_user_id = f2.asked_user_id
INNER JOIN users AS u ON f1.asked_user_id = u.id
WHERE f1.status = 1 AND f2.status = 1
AND f1.asker_user_id = 2
) a
LEFT JOIN connections c ON c.user_id = a.friend_id
AND c.invisible <> 1 AND c.deleted <> 1
LEFT JOIN words_en w ON c.word_id = w.id
GROUP BY 1
) b
LEFT JOIN messages m ON m.to_user_id = 2
AND m.from_user_id = b.friend_msg_id
AND m.seen = 0
LEFT OUTER JOIN
(
SELECT b.user_id AS friend_id, GROUP_CONCAT(c.word) AS words_in_common
FROM connections a
INNER JOIN connections b
ON a.word_id = b.word_id
INNER JOIN words_en c
ON b.word_id = c.id
WHERE a.user_id = 2
GROUP BY b.user_id
) words_common
ON b.friend_msg_id = words_common.friend_id
GROUP BY b.name_surname, b.avatar, b.friend_words, b.friend_msg_id
ORDER BY unread_msg DESC

Converting nested select into join

My query is
select COUNT(*) from result
where test_id in (select test_id
from test_schedule
where scheduler_id in (select user_id
from users
where user_type=1))
Try this:
SELECT COUNT(r.*)
FROM result r
INNER JOIN test_schedule s ON r.test_id = s.test_id
INNER JOIN users u ON s.scheduler_id = u.user_id
WHERE u.user_type = 1
SELECT COUNT(*)
FROM result r
JOIN (SELECT DISTINCT test_id
FROM test_schedule s
JOIN users u ON s.scheduler_id = u.user_id
WHERE u.user_type = 1) s
USING (test_id)
The DISTINCT is necessary to keep rows from being multiplied by all the rows in the other tables that match.
SELECT COUNT(r.*)
FROM result r
RIGHT JOIN test_schedule s USING(test_id)
RIGHT JOIN users u ON s.scheduler_id = u.user_id
WHERE u.user_type = 1