mysql query, select the top comment according votes - mysql

i have 2 tables comments | votes
the `votes` structure
[`id` | `user_id` | `comment_id` | `rating`]
and the comments has the comment_id as the primary ok?
now i want get the top comments according to the sum of rating
[rating is 0 or 1]
and i want to get the top users too

Top Comments
This assumes comments table has a column named comments_id
SELECT A.* FROM comments A INNER JOIN (SELECT comment_id,SUM(rating) sumrating FROM votes GROUP BY comment_id) B USING (comment_id) ORDER BY B.sumrating;
This assumes comments table has a column named id
SELECT A.* FROM comments A INNER JOIN (SELECT comment_id,SUM(rating) sumrating FROM votes GROUP BY comment_id) B ON A.id = B.comment_id ORDER BY B.sumrating;
Top Users
This assumes users table has a column named user_id
SELECT A.* FROM users A INNER JOIN (SELECT user_id,SUM(rating) sumrating FROM votes GROUP BY user_id) B USING (user_id) ORDER BY B.sumrating;
This assumes users table has a column named id
SELECT A.* FROM users A INNER JOIN (SELECT user_id,SUM(rating) sumrating FROM votes GROUP BY user_id) B ON A.id = B.user_id ORDER BY B.sumrating;
Top Users and Comments
This assumes comments table has a column named comments_id and users has a column named user_id
SELECT B.* , C.* FROM
(SELECT comment_id,user_id,SUM(rating) sumrating FROM votes GROUP BY comment_id,user_id) A
comments B,users C,
WHERE A.comment_id=B.comment_id
AND A.user_id=C.user_id
ORDER BY A.sumrating,C.user_id,B.comment_id;
Give it a Try !!!

Related

How to run where exists with distinct faster

I have a query with WHERE EXISTS and DISTINCT. I just want to find distinct emails with same order_id
How can I make this faster
select DISTINCT(user_email)
from (
SELECT *
FROM orders mto
WHERE EXISTS
(
SELECT 1
FROM orders mti
WHERE mti.order_id = mto.order_id
LIMIT 1, 1
)
) as z
INNER JOIN marketplaces as u ON z.ump_id = u.id
You are doing excess/needless work - the EXISTS will always return TRUE in your situation.
If you want a list of all (unique) emails which have at least 1 order, then
SELECT
user_email
FROM
marketplaces
LEFT JOIN
orders ON ump_id = marketplaces.id
WHERE orders.id IS NOT NULL
GROUP BY user_email
If you want to get a list with all (unique) emails for a given order ID, then
SELECT
user_email
FROM
orders
LEFT JOIN
orders ON ump_id = marketplaces.id
WHERE orders.id = 17
GROUP BY user_email

MySQL Query for Subtraction of 2 fields with decimal(13,2)

How do you subtract (2)two different fields with the same data type of decimal(13,2) ?
I have table for users
attribtues:
id, name, password, email, deleted, created_at, updated
and
table for top_up_history
attributes:
id, userId, paymentId, paymentDesc, amount, deleted, created_at, updated_at
and
table for transaction_details
id, userId, merchId, transId, amount, refCode, procId, deleted, created_at, updated_at
and
I have view for user_balance
attributes:
userId, total_topup, total_balance
Here's my current query:
SELECT a.id as userId, SUM(b.amount) as total_topup,
SUM(b.amount) - SUM(c.amount) as total_balance
FROM `users` AS a LEFT JOIN `top_up_history` AS b
ON a.id = b.userId LEFT JOIN`transaction_details` as c
ON a.id = c.userId GROUP BY a.id
Now the current output of this user_balance is this:
But the problem is
the data from transaction_details is:
the data from top_up_history
the data from users
There's something wrong with my computation.
The output should be:
userId total_topup total_balance
1 NULL NULL
2 NULL NULL
3 15000 14,725
9 10150 9,875
you should manage the null value
SELECT a.id as userId
, SUM(ifnull(b.amount,0)) as total_topup
, SUM(ifnull(b.amount,0)) - SUM(ifnull(c.amount,0)) as total_balance
FROM `users` AS a
LEFT JOIN `top_up_history` AS b ON a.id = b.userId
LEFT JOIN`transaction_details` as c ON a.id = c.userId
GROUP BY a.id
Just take a look at resulting table without GROUP BY function.
LEFT JOIN top_up_history produces two rows for each unique user,
It caused by repeated userId values (9 and 3) in top_up_history table. At this moment (before joining transaction_details) you already have 6 rows. Now sql joins transaction_details and duplicates its amount column value for each matched row.
Then, finally you group, and sum duplicated values. Substruction itself works ok.
The easiest way to deal with that kind of problem is to do subquery like so:
SELECT a.id as userId, SUM(b.amount) as total_topup,
SUM(b.amount) -
(select sum(tr.amount) from transaction_details_ as tr where tr.users_id = a.id) as total_balance
FROM users_ AS a
LEFT JOIN top_up_history_ AS b ON a.id = b.users_id
LEFT JOIN transaction_details_ as c ON a.id = c.users_id
GROUP BY a.id

Left Join with last insert record from left table and all record form right table

fetch data with join with last insert record from left table based on company id and all record from right table doesn't matter it has any match record in left table.
**company_list**
id
company_id
company_name
company_address1
company_address2
company_phone
company_headoffice
active
**company_subscription_list** table field name is
id
company_id
company_name
company_address1
company_address2
company_phone
company_headoffice
active
and i am using this query for fecth record
SELECT *, c.id AS main_id
FROM company_list as c
LEFT JOIN company_subscription_list as s ON c.company_id = s.company_id
where s.id IN (select max(id) from company_subscription_list GROUP BY company_id)
but its not showing result of those company who didn't subscribe yet.
Need Help.
You have to put you condition in your join condition. Doing so, you will not lose lines :
SELECT *, c.id AS main_id
FROM company_list as c
LEFT JOIN company_subscription_list as s
ON c.company_id = s.company_id
AND s.id IN (select max(id) from company_subscription_list GROUP BY company_id)
Try on this link : http://sqlfiddle.com/#!9/5db87/4

SQL query with count() from another table

I got the following tables:
pictures
------------------------------------
id
name
views
votes
------------------------------------
id
user_id
pic_id
I want to get a result from a query that will give me each picture id, with the views of the picture, and the total votes from the table votes for the specific pic_id
example:
pictures.id, pictures.views, total votes
1 ------------ 78------------------ 123
2 ------------ 23------------------- 69
and so on...
The code I tried:
SELECT `pictures`.`id`,`pictures`.`views`, COUNT(`votes`.`pic_id`) as votes
FROM `pictures`
JOIN `votes`
ON `pictures`.`id` = `votes`.`pic_id`
But it doesn't give me the reuslt I desire.
You need to have GROUP BY clause.
The use of LEFT JOIN will display all records on table pictures with or without matching record on table votes.
SELECT a.id, a.name, a.views,
COUNT(b.pic_id) TotalVotes
FROM pictures a
LEFT JOIN votes b
ON a.id = b.pic_id
GROUP BY a.id, a.name, a.views
Use left join with a group function ,normal join keyword means an inner join and you need a left join for one to many relation
SELECT `pictures`.`id`,`pictures`.`views`, COUNT(`votes`.`pic_id`) as votes
FROM `pictures`
LEFT JOIN `votes`
ON `pictures`.`id` = `votes`.`pic_id`
GROUP BY `pictures`.`id`
Try this:
SELECT `pictures`.`id`,`pictures`.`views`, COUNT(`votes`.`pic_id`) as votes
FROM `pictures`
JOIN `votes`
ON `pictures`.`id` = `votes`.`pic_id`
GROUP BY `votes`.`pic_id`;
You need to try like this using the GROUP BY clause:
SELECT `pictures`.`id`,`pictures`.`views`, COUNT(`votes`.`pic_id`) as votes
FROM `pictures`
JOIN `votes`
ON `pictures`.`id` = `votes`.`pic_id`
group by `pictures`.`id`

SELECT count(*) on Intermediary Table with Many-Many relationship Only if Exists in Both Related Tables

I have 3 tables: users, courses and courseusers. Courseusers is the intermediary table that joins courses.idCourse with users.idUser. However, the intermediary table has no foreign key constrains and ON DELETE CASCADE or ON UPDATE CASCADE.
Users:
idUser|name
Courses:
idCourse|name
Courseusers:
id|idUser|idCourse
My question is, how do I get the top 3 most subscribed courses (most entries in courseuser), while ignoring manually deleted users from the users and courses tables (they will still exists as entries in courseuser).
What I have right now:
SELECT c.idCourse, c.name, count(*) as count
FROM courseusers as cu
JOIN course as c
ON cu.idCourse=c.idCourse
JOIN users as usr
ON (usr.idUser=u.idUser)
GROUP BY u.idCourse
ORDER BY count DESC
LIMIT 3
Try to use the following query
SELECT c.idCourse, c.name, count(*) as count
FROM courseusers as cu
LEFT JOIN course as c
ON cu.idCourse=c.idCourse
LEFT JOIN users as usr
ON (usr.idUser=u.idUser)
GROUP BY u.idCourse
ORDER BY count DESC
LIMIT 3
http://sqlfiddle.com/#!2/0567a/1
SELECT
c.name,
COUNT(1) AS total
FROM Courceusers cu
JOIN Cources c USING(idCource)
JOIN Users u USING(idUser)
GROUP BY 1
ORDER BY 2 DESC
LIMIT 3;
Join all tables based on table Users not on the intermediary table
SELECT a.idUser, a.Name, COUNT(c.idCourse) totalCount
FROM Users a
INNER JOIN CourseUsers b
ON a.idUser = b.idUser
INNER JOIN Courses c
ON b.idCourse = c.idCourse
GROUP BY a.idUser, a.Name
ORDER BY totalCount DESC
LIMIT 3
select
CourseUsers.idCourse,
Courses.name,
COUNT(distinct CourseUsers.idUser) as Subscribers
from CourseUsers
inner join Courses on CourseUsers.idCourse = Courses.idCourse
inner join Users on CourseUsers.idUser = Users.idUser
group by CourseUsers.idCourse, Courses.name
order by Subscribers desc
limit 3