I want to retrieve the name of the user with the top 10 most voted post.
the formula in calculating the votes should be upvotes-downvotes. I also need to count the votes of that post.
Here's my
table user_info
id lname fname
1 abc1 abc1
2 abc2 abc2
3 abc3 abc3
4 abc4 abc4
5 abc5 abc5
6 abc6 abc6
7 abc7 abc7
table post
post_id post_message user_id
1 sup 1
2 good morning 2
3 hello 5
4 test 3
5 sample 4
table vote
vote_id user_id post_id vote_type
1 1 1 upvote
2 2 1 upvote
3 1 2 downvote
4 1 2 upvote
5 2 2 downvote
6 3 1 upvote
7 3 4 upvote
8 4 4 downvote
here's the query that I tried.
SELECT post_id, fname,lname,COUNT(CASE WHEN vote_type = 'upvote' then 1 ELSE NULL END) as "upvotes", COUNT(CASE WHEN vote_type = 'downvote' then 1 ELSE NULL END) as "downvotes"
FROM user_info
LEFT JOIN post ON
post.user_id = user_info.id
LEFT JOIN vote ON
post.user_id = user_info.id
ORDER BY 'upvotes'- 'downvotes' // is this possible?
LIMIT 10
My desired output is something like this.
post_id lname fname vote
1 abc1 abc1 3 // 3 upvotes
4 abc3 abc3 0 // 1upvote - 1 downvote
3 abc5 abc5 0 // no vote
5 abc4 abc4 0 // no vote
2 abc2 abc2 -1 // 1upvote - 2 downvotes
I don't know where I should put that column "vote" but it should be there in my query.
I created an sql fiddle for this
Fiddle
select p.post_id,u.fname,u.lname,
case when sum(upvotes)+sum(downvotes) is null then 0
else sum(upvotes)+sum(downvotes) end as vote
from post p left join
(
SELECT post_id,
CASE WHEN vote_type = 'upvote' then 1 ELSE 0 END as "upvotes",
CASE WHEN vote_type = 'downvote' then -1 ELSE 0 END as "downvotes"
FROM vote
) t
on p.post_id = t.post_id
left join user_info u on p.user_id = u.id
group by p.post_id
order by vote desc, sum(upvotes) desc, sum(downvotes) desc
limit 10;
Related
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
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;
I need to select user_id & quiz_id, for users which their count of questions in their quiz = sum of correct, this mean they answer 100% correct
answers table:
quiz_id question_id user_id answer_id correct
1 1 1 1 1
1 2 1 6 0
1 3 1 9 1
2 1 2 1 1
2 2 2 5 1
3 4 1 17 1
3 5 1 21 1
3 6 1 25 1
4 1 3 1 1
5 4 4 18 0
6 1 5 1 1
6 2 5 5 1
7 1 3 2 0
7 2 3 7 0
ex 1:
user 1 took "quiz_id" = 1
count of questions in "quiz_id = 1" = 3
sum of correct = 2
so it's not 100%
user_id = 1 in quiz_id = 1 => will not selected
but user_id = 1 will be selected with quiz_id = 3 cause he got 100%
expected results:
quiz_id user_id
2 2
3 1
4 3
6 5
notes:
quiz could be taken with different users with different number of
questions
quiz_id, user_id unique together (user can not take same quiz twice)
thanks,
You should use an aggregate query with HAVING clause:
SELECT quiz_id, user_id
FROM quiz_answer -- or whatever the name is
GROUP BY quiz_id, user_id
HAVING COUNT(question_id) = SUM(correct)
here you must use HAVING instead of WHERE because
The HAVING clause can refer to aggregate functions, which the WHERE
clause cannot
as specified in the docs.
I have join with a multiple tables. You can find the tables and MySQL query in this demo.
These are the tables:
users
id name
1 abc
2 xyz
3 pqr
friend
user_id friend_id
1 2
1 3
2 3
collection
id user_id friend_id amount
1 1 2 100
2 2 1 -100
3 2 3 200
4 3 2 -200
5 1 3 300
6 3 1 -300
bill
id use_id(bill_creator)
1 1
2 2
3 2
bill_person
id bill_id user_id
1 1 1
2 1 2
3 1 3
4 2 2
5 2 3
6 3 2
6 3 1
So far I have made this query:
SELECT mf.id
, mf.name
, c.amount AS amount,count(bp.user_id) AS no_common_bills
FROM (
SELECT fr.user_id AS user_id
, fr.friend_id AS friend_id
FROM friend fr
JOIN users fru
ON fru.id = fr.user_id
WHERE fru.id IN (1)
UNION
SELECT fl.friend_id AS user_id
, fl.user_id AS friend_id
FROM friend fl
JOIN users flf
ON flf.id = fl.friend_id
WHERE flf.id IN (1)
) f
JOIN users mf
ON mf.id = f.friend_id
LEFT
JOIN collection c
ON c.friend_id = mf.id
AND c.user_id = f.user_id
LEFT JOIN bill_person bp
ON bp.user_id=f.user_id AND c.friend_id = mf.id
GROUP BY mf.id
ORDER BY mf.id
and my output of this query is
id NAME AMOUNT NO_COMMON_BILLS
2 XYZ 100 2
3 PQR 300 2
but I want this result:
id NAME AMOUNT NO_COMMON_BILLS
2 XYZ 100 2
3 PQR 300 1
I am getting wrong output at NO_COMMON_BILLS. Other than that, all values are correct.
Third time's a charm...
http://sqlfiddle.com/#!2/338dd/12
SELECT u.name friend
, COUNT(bp2.user_id) no_common_bills
FROM users u
LEFT
JOIN
( SELECT user_id me, friend_id them FROM friend WHERE user_id = 1
UNION
SELECT friend_id,user_id FROM friend WHERE friend_id = 1
) x
ON x.them = u.id
LEFT
JOIN bill_person bp1
ON bp1.user_id = x.them
LEFT
JOIN bill_person bp2
ON bp2.bill_id = bp1.bill_id
AND bp2.user_id = x.me
WHERE u.id <> 1
GROUP
BY friend;
FRIEND NO_COMMON_BILLS
jkl 0
mno 0
pqr 1
xyz 2
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: