Filter count table query - mysql

i have 2 tables as following.
User
id name
---------------
1 john
2 raju
3 manu
4 raghu
friendtable
id userid recvId
------------------------
1 1 2
2 1 3
3 2 3
4 3 4
Is it possible to filter users by their friends count from these tables.Please help me.
For eg :- range >=3 will result : john,manu
range >3 and range <2 will result : raju
range <2 result : raghu

Do a UNION ALL to get all id's from friendstable in one column. Join users table with that result.
Do a GROUP BY, adjust HAVING to decide what to return, e.g. at least 3 times etc.
select u.name
from users
join (select userid as id from friendtable
union all
select recvId as id from friendtable) f
on u.id = f.id
group by u.name
having count(*) >= 3

SELECT name FROM user a,friendtable b WHERE a.id=b.id AND b.recvid>=3
SELECT name FROM user a,friendtable b WHERE a.id=b.id and b.recvid>3 AND b.recid<2
SELECT name FROM user a,friendtable b WHERE a.id=b.id AND b.recid<2

Related

Mysql count(*) based in two relations

I would like to count(*) how much customers have created a post or made a comment. If the same customer has made several posts and comments, it should count only once.
Customer Table:
ID Name ...
1 Jonh
2 Mark
3 King
4 Doe
Post Table:
ID USER_ID...
1 1
2 1
3 3
4 1
Comment Table:
ID USER_ID...
1 1
2 3
3 3
4 4
It should return count(*) = 3
(user_id: 1, 3 and 4).
Try this one. It worked for me and returns what you're looking for:
SELECT COUNT( USER_ID ) AS TOTAL
FROM (
SELECT USER_ID
FROM POSTS
UNION
SELECT USER_ID
FROM COMMENTS
)X
I used POSTS and COMMENTS as table names bc I was unsure what your exact table names are, so make sure to change these in your query.
This should work:
SELECT COUNT(DISTINCT USER_ID) FROM (
SELECT USER_ID FROM POST_TABLE
UNION
SELECT USER_ID FROM COMMENT_TABLE
)

Mysql Group by counting issue

Database structure
Table 'applicants'
id org_id team_id
1 1 1
Table 'teams'
id name
1 Test
Table 'teams_members'
id team_id user_id
1 1 1
2 1 2
Table 'users_playeraccounts'
id user_id summoner_id rank_solo
1 1 1 5
2 1 2 8
3 2 3 7
select sum(rank_solo) as rank_sum,
max(rank_solo) as highest_rank,
count(tt.id) as members,
t.name,
o.team_id
from applicants o
join teams t on o.team_id = t.id
join teams_members tt on t.id = tt.team_id
join users_playeraccounts p on tt.user_id = p.user_id
where org_id = :org
group by team_id
This offcourse gives me a result like
rank_sum highest_rank members name team_id
20 8 3 Test 1
Is there a way for me to get both the count of members with their playeraccounts aka
If 1 user has 2 it'll be 2
And also a way for me to keep it as 1 so it literally just counts the rows found in teams_members neglecting the entries in users_playeraccounts?
I want to receive both 2 and 3 as a result of my query.
You want to count the distinct number of entries in tt.id, so you can do that like this:
SELECT ... COUNT(DISTINCT tt.id) AS distinct_members ...
Rather than giving you a count of every row that has a non-null tt.id, you'll get a count of the number of unique values.

My SQL query to retrieve 4 columns based on unique records from two columns

Hi I'm trying to write a correct query for MySQL to retrieve values from 4 columns (from, to, content, date or all if that's easier) based on 2 columns being unique in the same table. The idea is to retrieve a list of only last messages sent and received by a user X
TABLE
msg_id|msg_from|msg_to|msg_new|msg_content|date
1 user1 sw1 1 message1 2014-02-06
2 user1 sw1 1 message2 2014-02-06
3 user1 sw3 0 message3 2014-02-06
4 user1 sw5 0 message4 2014-02-06
5 sw2 sm2 1 message5 0000-00-00
6 sw2 sm4 1 message6 2014-02-20
7 sw1 user1 1 message7 2014-02-20
8 user1 sw5 1 message8 2014-02-20
My last attempt :
SELECT t1.* FROM (SELECT MAX(msg_id) AS nr, msg_from, msg_to
FROM com_msg GROUP BY msg_from) AS t2
INNER JOIN com_msg t1 ON t1.msg_from=t2.msg_from AND t1.msg_id=t2.nr
WHERE t1.msg_to='sw1' OR t1.msg_from='sw1'
which returns :
2| user1|sw1 |1|message2|2014-02-06
7| sw1 |user1|1|message7|2014-02-20
but should only return :
7| sw1 |user1|1|message7|2014-02-20
If I understant your question correctly, this query should return what you need:
SELECT com_msg.*
FROM com_msg INNER JOIN (SELECT MAX(msg_id) max_id
FROM com_msg
WHERE 'sw1' IN (msg_from, msg_to)
GROUP BY
CASE WHEN msg_from!='sw1' THEN msg_from
ELSE msg_to END) m
ON com_msg.msg_id = m.max_id
IDs needs to be ordered, otherwise you should use MAX(date)
Please see fiddle here.
Basically, you need to wrap this with another query, because your where clause is showing you records where either the to or the from equal the user. I'm not a MySQL guru, but you should be able to do something like this:
select top 1 *
FROM (
SELECT t1.* FROM (
SELECT MAX(msg_id) AS nr, msg_from, msg_to
FROM com_msg
GROUP BY msg_from
) AS t2
INNER JOIN com_msg t1 ON t1.msg_from=t2.msg_from AND t1.msg_id=t2.nr
WHERE t1.msg_to='sw1' OR t1.msg_from='sw1'
)
ORDER BY date DESC
This will return the most recent entry from your results based on the date.
If you are looking for just a single record returned of the last email like your example shows, this should do it...
Select TOP 1 msg_from, msg_to, msg_content, date
From com_msg
Where msg_from='sw1' OR msg_to='sw1'
ORDER BY msg_id DESC

How To write a SQL Select Query for this problem?

I have four tables: groups, users, votes, follows.
The structures of these tables are
groups
g_id g_title g_content
1 t1 content1
2 t2 content2
users
u_id u_groupid
1 1
2 1
3 2
4 2
5 2
votes
v_id v_userid v_groupid v_votes
1 1 1 1
2 1 2 1
3 2 2 1
4 3 2 1
5 3 1 1
follows
f_id f_userid f_groupid
1 1 1
2 2 1
3 2 2
4 3 1
5 3 2
The groups table records the basic information of a "group".
The users table keeps the relationship between users and groups, that is, if the user A belongs to groups B, then there will be a record in the user table.
The votes table means the supportive attitude that a user holds to a group.
If user A is interested in group A, then add a entry into the Follows table.
Now my problem is how to write one select statement to query the number of users, the number of votes and the number of followers of each group.
I want the query result likes this
g_id num_users unm_votes num_followers
1 2 2 3
2 3 3 2
By the way, my database is Mysql 5.0.51b.
If you want in 1 query, something like this will help you
SELECT g_id,
d1.num_users,
d2.unm_votes,
d3.num_followers
FROM groups gg
LEFT JOIN (SELECT g_id,
COUNT(u.u_id) AS num_users
FROM groups g
LEFT JOIN users u
ON u.u_groupid = g.g_id
GROUP BY g_id) d1
ON d1.g_id = gg.g_id
LEFT JOIN (SELECT g_id,
COUNT(v.v_userid) AS unm_votes
FROM groups g
LEFT JOIN votes v
ON v.v_groupid = g.g_id
GROUP BY g_id) d2
ON d2.g_id = gg.g_id
LEFT JOIN (SELECT g_id,
COUNT(f.f_userid) AS num_followers
FROM groups g
LEFT JOIN follows f
ON f.f_groupid = g.g_id
GROUP BY g_id) d3
ON d3.g_id = gg.g_id
GROUP BY gg.g_id
For the user count by group:
select g_id,count(u.uid) user_count from groups g, users u
where u.groupid = g.g_id
group by g_id
May want to read up on group by.

SQL Counting sums of rows

I have 2 tables.
Table 1: Fruits
id (int, autoincreasing, primary key)
some other junk
Table 2: Customers
has a 'fruit' column, this column contains an id from the fruit table.
i want to query all the customers, and come up with a list of all the fruit ID's and the number of times they are in use.
So this set up:
Fruits has
id name
1 orange
2 banana
3 apple
Customers has 6 rows like:
id fruit
1 1
2 1
3 2
4 2
5 2
6 3
Trying to write a query that Will give me:
fruit id purchase count
1 2
2 4
3 1
Try this
SELECT f.id as fruit_id, COUNT(1) AS purchase_count
FROM FRUITS f LEFT JOIN CUSTOMERS c
ON F.ID = c.fruit
GROUP BY f.id
Should just be a simple aggregate...
SELECT fruit_id, COUNT(fruit_id) AS purchase_count
FROM customers
GROUP BY fruit_id
ORDER BY fruit_id ASC;
untested
SELECT id, SUM(fruit) as "fruit id", "purchase count"
FROM Customers
GROUP BY id;