MYSQL getting SUM through joins - mysql

I'm looking for a possible solution that will give me TOP 3 users from users table who are ordered based on the turnover they made.
So here is my table schema for users and transactions table.
users TABLE
id inviter_id
1 1
2 1
3 1
4 1
5 2
6 3
7 5
8 6
9 1
10 3
11 9
12 1
13 5
14 7
15 11
EXPLANATION : The id represents user's unique ID and inviter_id represents the ID that invited the user.
transactions TABLE
id payer _id amount
1 2 200
2 2 100
3 2 50
4 2 10
5 3 400
6 4 200
7 5 100
8 6 50
9 7 100
10 8 50
11 9 50
12 10 100
13 11 400
14 2 200
15 2 100
16 2 50
17 2 10
18 4 500
Here payer_id represents the users in users table.
Desired Output :
user_id turnover
//ID 1 should not be included in this table.
2 100 //ID 5 in `users` is referral of ID 2 so summing whatever ID 5 from `transactions` table using `payer_id` column we get : 100 (Sme process for other rows too)
3 150 //ID3's referrals : 6,10 | 50+100
4 0 //ID4's invited no one
5 100 //ID5's referrals : 7,13 | 100
6 50 //ID 6's referrals : 8 | 50
7 100 // ID 7's referrals : 14 | 0 (No rows for ID 14 in transactions table)
8 0 //No referrals invited
9 400 //ID9's referrals : 11 | 400
10 0 //No referrals invited
11 0 //ID11's referrals : 14 | 0 (No rows in txn table)
12 0 //No referrals invited
13 0 //No referrals invited
14 0 //No referrals invited
15 0 //No referrals invited
FIRST let me explain how I calculate turnover :
For each id from users table, Let's take id:1 as example. I check the 'inviter_id' column for 2. So whoever has the value as 2 in inviter_id column, those ids are considered as id 2's referral.
So I need the sum of amount all the referrals of id 2 has paid. Similarly for other ids and they should be sorted by the highest turnover.
What I tried so far :
here is my code.
select u.id AS user_id, u.address AS address, SUM(turnover) AS turnover
from users u left join
(select ur.id, ur.inviter_id, SUM(mt.userTurnover) as turnover
from users ur left join
(select m.payer_id, SUM(m.amount) as userTurnover
from matrix m where m.created >= $content_start AND m.type = 'escrow'
group by m.payer_id
) mt
on mt.payer_id = ur.id
where ur.created >= $content_start
group by ur.inviter_id
) ui
on ui.inviter_id = u.id
WHERE u.id != 1 AND u.id != 2 AND u.id != 3 AND u.id != 4
group by u.id
order by turnover desc LIMIT 10;
I'm getting the sum of amounts of the user itself instead of the user's each and every referral's paid amount.

SELECT u1.id, COALESCE(SUM(tr.amount), 0) turnover
FROM users u1
LEFT JOIN users u2 ON u1.id = u2.inviter_id
LEFT JOIN transactions tr ON u2.id = tr.payer_id AND u2.id != u2.inviter_id
GROUP BY u1.id
fiddle
If you need total payment sum for usrs.id = 1 (i.e. including self-referenced) then remove AND u2.id != u2.inviter_id.
If you do not need the final row for users.id = 1 then add according WHERE condition.

Related

select user whose child is less than 2

i have table structure like this
id
user_id
parent_id
club
1
1
club1
2
2
1
club1
3
3
1
club1
4
4
2
club1
5
5
2
club1
6
6
3
club1
7
7
3
club1
8
8
4
club1
9
9
4
club1
10
10
5
club1
11
11
5
club1
12
12
6
club1
13
13
6
club1
14
14
7
club1
15
15
7
club1
i want to select user_id whose child is less then 2.
refer to above table user 1,2,3,4,5,6 and 7 two child complete so the query should return 8,9,10,11,12,13,14,15
Refer to above table here user_id 1 have two child 2 and 3 , user_id 2 have child 4 and 5 and so on.
i need to select user_id whose child is less than 2
You can do it as follows :
SELECT user_id
FROM club_tree
WHERE user_id NOT IN (
SELECT parent_id
from club_tree
where club = 'club1'
group by parent_id
HAVING count(1) >= 2
)
and club = 'club1';
We Select users that are not in the list of users with more than two childs.
This is to get users with more than two childs :
SELECT parent_id
from club_tree
group by parent_id
HAVING count(1) >= 2
Here you can test it : http://sqlfiddle.com/#!9/eb2c70/3
Can you try this query using left join :
SELECT c.user_id
from club_tree c
left join
(
select parent_id
from club_tree
where club = 'club1'
group by parent_id
HAVING count(1) >= 2
) as c2 on c.user_id = c2.parent_id
where c.club = 'club1' and c2.parent_id is null;
Try it here : http://sqlfiddle.com/#!9/eb2c70/17

How to fetch count from the sub-table with multiple date

I have a user table
id
name
number
created_at
1
User1
102
2022-02-03
2
User2
103
2022-02-06
3
User3
123456
2022-02-07
4
User4
1234567
2022-02-07
5
User5
1234568
2022-04-08
and invite table
id
invited_by
invited_to_number
created_at
1
1
123456
2022-04-05 12:03:03
2
2
123456
2022-04-05 17:13:23
2
1
1234567
2022-04-07 17:13:23
2
1
1234568
2022-04-07 17:13:23
2
2
1234565
2022-04-08 17:13:23
I need user table records along with the count of all invited registered in
all-time accepted in
Today accepted in
yesterday accepted in
with the group by number using MySQL Query
Count will only go to those users who were invited first
and after successfully registered count will add to the invited the user
So, the Expected result is
Today Date: 2022-04-08
id
name
all_time_accepted
Today's accepted
yesterday accepted
1
User1
3
1
1
2
User2
0
0
0
3
User3
0
0
0
4
User4
0
0
0
5
User5
0
0
0
If you want to count only today's or yesterday's invites, place a boolean condition (like DATE(i.created_at) = #today_date) inside the select expression. The condition will evaluate to 1 (if true) or 0 (if false), which means that if you SUM(), you will get the number of rows satisfying this condition.
SELECT
u.id,
u.name,
SUM(
u1.id IS NOT NULL
AND i1.id IS NULL
) AS all_time_accepted,
IFNULL(SUM(
u1.id IS NOT NULL
AND i1.id IS NULL
AND DATE(i.created_at) = #today_date
), 0) AS today_accepted,
IFNULL(SUM(
u1.id IS NOT NULL
AND i1.id IS NULL
AND DATE(i.created_at) = #today_date - INTERVAL 1 DAY
), 0) AS yesterday_accepted
FROM
(SELECT #today_date := CURDATE()) AS var,
`user` u
LEFT JOIN `invite` i
ON i.invited_by = u.id
LEFT JOIN `user` u1
ON u1.number = i.invited_to_number
LEFT JOIN `invite` i1
ON i1.invited_to_number = i.invited_to_number
AND i1.created_at < i.created_at
GROUP BY u.id

Get user who had no activity in from last 12 months

I want to make SQL that will return users who not performed any points/redeem activity in last 12 months
user_data
userId email create_date
1 steve#gmail.com 2017-01-05 12:55:00
2 mark_nel#gmail.com 2019-05-15 12:13:00
3 les.born#gmail.com 2018-04-05 03:15:00
points_data
id user_id activity_id activity_points create_date
1 1 1 10 2017-01-05 11:09:00
2 2 1 15 2019-06-12 09:17:00
3 2 2 10 2019-08-05 02:55:00
4 3 1 10 2019-01-05 07:15:00
redeem_data
id user_id redeem_points create_date
1 2 20 2019-09-11 02:55:00
Result
email
steve#gmail.com
Use LEFT JOIN concept to include non matching row from table user_data and only select non matching row by removing matching rows using where id of both tables(points_data,redeem_data) is null.
SELECT u.email
FROM user_data u
LEFT JOIN points_data p ON u.userId = p.user_id AND p.create_date >= CURRENT_DATE - INTERVAL 1 YEAR
LEFT JOIN redeem_data r ON u.userId = r.user_id AND r.create_date >= CURRENT_DATE - INTERVAL 1 YEAR
WHERE p.id IS NULL AND r.id IS NULL;

Mysql SUM 0 when not in another table

I have 2 tables:
users:
id | name | club_id |
1 Bob 4
2 Jane 5
3 Alex 4
4 Paul 4
5 Tom 4
points:
user_id | club_id | amount(can vary)
1 4 10
1 2 10
2 5 10
3 4 10
3 4 10
4 4 10
3 2 10
3 4 10
I need (where users.club_id = 4 AND points.club_id = 4):
user_id | name | sum(amount)
3 Alex 30
1 Bob 10
4 Paul 10
5 Tom 0
Notice Tom is present in users but doesn't have any entries in points, so his sum should be 0. This is what throws me off in conjuction with grabbing a list from users.
Also would like this to be as efficient as possible (hence I added club_id = 4 both in users and points)
Try this:
SELECT
u.id,
u.name,
COALESCE(SUM(p.amount), 0) AS Totalpoints
FROM
(
SELECT *
FROM users
WHERE club_id = 4
) AS u
LEFT JOIN
(
SELECT *
FROM points
WHERE club_id = 4
) AS p ON p.user_id = u.id
GROUP BY u.id,
u.name;
See it in action here:
SQL Fiddle Demo
try this query
select u.id, u.name, sum(if (p.amount is null, 0, p.amount)) as totalPoint
from
user u
left join
(select * from point p where p.club_id = 4)p
on u.id = p.user_id
where u.club_id=4
group by u.id
SQL FIDDLE:

Count number of retweeted tweets and total number tweets have been retweeted

Consider the following tables
users tweets
--------------------------------- ---------------------------
user_id num_retweets sum_retweets tweet_id user_id retweeted
--------------------------------- ---------------------------
1 1 1 3
2 2 1 0
3 3 1 4
4 2 0
5 2 0
6 3 1
7 3 2
8 3 0
I want to count num_retweets: the number of times a users has written a retweet that has been retweeted and sum_retweets: the number of times all of a users tweets have been retweeted. The expected users table after the UPDATE query is:
users
---------------------------------
user_id num_retweets sum_retweets
---------------------------------
1 2 7 <-- 3 + 4
2 0 0
3 2 3 <-- 1 + 2
Any help on building these two queries would be greatly appreaciated :-) I keep having trouble performing UPDATEs across tables.
UPDATE
USERS u
JOIN (
SELECT
tweets.user_id,
COUNT(IF(tweets.retweeted > 0, 1, null)) as num_retweets,
SUM(tweets.retweeted) as sum_retweets
FROM tweets
GROUP BY tweets.user_id
) as t ON t.user_id = u.user_id
SET u.num_retweets = t.num_retweets, u.sum_retweets = t.sum_retweets