mysql different select queries in one - mysql

how can I have with one query the following:
I would like to have from my comments table all the people how have been commenting on a given post_id and than check how many time the user has commented, based on his name. I would like to avoid to have 2 different queries for it
I have been trying the following but won't return to expected result
SELECT comments.*, COUNT(approved.comment_approved) AS has_commented FROM wp_comments AS comments
INNER JOIN wp_comments AS approved
ON comments.comment_author = approved.comment_author
WHERE comments.comment_post_ID =14616
GROUP BY comments.comment_content

Shouldn't you group by post_ID ? (that would return only one line)
SELECT
comments.*
, COUNT(approved.comment_approved) AS "has_commented"
FROM wp_comments AS comments
JOIN wp_comments AS approved
ON (comments.comment_author = approved.comment_author)
WHERE comments.comment_post_ID = 14616
GROUP BY comments.comment_post_ID
;
Or do you want one line per "approved" comment ?

Related

Group different counted values in a single row

Sql fidle here.
SELECT UserId,totalLikes FROM Users
LEFT JOIN(select ownerId, PostId from Posts) a ON ownerId = UserId
LEFT JOIN(select idOfPost, count(idOfPost) AS totalLikes from Likes) b ON idOfPost = PostId
WHERE UserId = 120 GROUP BY UserId
This is a simplified part of the query that i am using, on the fiddle it works exactly how i need it to, it counts every idOfPost as a like for every post that belongs to the user specified, in this case where UserId = 120
and it groups the result in a single row.
But when i run this in WAMP i am getting the following error #1140 this is incompatible with sql_mode=only_full_group_by witch i think is because i need to group by PostId as well, but if i do that i get multiple rows, naturally because the id of the posts are different but i want to have it in a single row.
So my questions are: Should i disable the sql_mode=only_full_group_by witch i'm not really sure what impact would have, or is my tables structure at fault and it needs to be changed, maybe including the UserId in the Likes table, or my query is at fault and needs to be changed?
mysql version 5.7.14 on WAMP
Use GROUP BY in the subquery and sum() aggregate in the main query:
SELECT UserId, sum(totalLikes) AS totalLikes
FROM Users
LEFT JOIN Posts a ON ownerId = UserId
LEFT JOIN (
select idOfPost, count(idOfPost) AS totalLikes
from Likes
group by idOfPost) b ON idOfPost = PostId
WHERE UserId = 120
GROUP BY UserId
SqlFiddle.

#1052 - Column 'status' in field list is ambiguous

SELECT
repeats.id,user_id,deposit_id,repeat_time,made_time,rebeat,status,created_at,updated_at
FROM repeats
INNER JOIN users ON users.id = repeats.user_id
I am trying to merge two tables; users and repeats, but it is giving following error.
Error
SQL query: Documentation
SELECT repeats.id
,user_id
,deposit_id
,repeat_time
,made_time
,rebeat
,status
,created_at
,updated_at
FROM repeats
INNER JOIN users
ON users.id = repeats.id
LIMIT 0, 25
MySQL said: Documentation
#1052 - Column 'status' in field list is ambiguous
Both your repeats and users tables seem to have a status column. You need to fully qualify the column in your query. E.g.:
SELECT repeats.id,
user_id,
deposit_id,
repeat_time,
made_time,
rebeat,
repeats.status, -- Or users.status, depending on what you need
created_at,
updated_at
FROM repeats
INNER JOIN users ON users.id = repeats.user_id
Whenever you have more than one table in a query, you should also qualify the column names. Another good practice is to use table aliases that are abbreviations for the table names.
I don't know what your data looks like, but the query would be something like:
SELECT r.id, r.user_id, r.deposit_id, r.repeat_time, r.made_time, r.rebeat,
u.status, u.created_at, u.updated_at
FROM repeats r INNER JOIN
users u
ON u.id = r.user_id;
This is just a guess. You have to correctly qualify the names.

use COUNT(*) values from one table to another

Suppose I have two tables, users and posts. Posts has the following fields, userid, postid, etc and userid can appear multiple times as one user can write multiple posts....I'm just trying sort the users table based off the # of occurrences per userid in the posts table. I can get the # of occurrences per user using this
SELECT userid, COUNT(*)
FROM posts
GROUP BY userid;
I would like to use the values under COUNT(*) column, maybe add it to my other table because then I can simply to something like this
SELECT * FROM users
ORDER BY newcolumn ASC;
but I'm having trouble doing that. Or can I do it without having to add an extra column? Hints please. Thanks
Left join is the key here!
SELECT users.userid,count(posts.userid) AS total_count
FROM users
LEFT JOIN posts on posts.userid = users.userid
GROUP BY users.userid
ORDER BY total_count DESC;
We are taking the left join on two tables with same user_id and we are counting the total number of posts per user using group by. Finally sort by count and show results.
try an left join:
select users.userid, [user fields],count(postid) as posts_count
from users
left join posts on posts.userid = users.userid
group by users.userid,[user fields]
order by posts_count desc.
You want to select users (FROM users) but you want to sort based on criteria in another table (COUNT(*) FROM posts) -- therefore you need to use a JOIN
Off-hand I can't seem to recall if "JOIN" or "RIGHT JOIN" or "FULL JOIN" is what you need if you wanted to get a cartesian product of the tables then group and aggregate on a single field, but I can avoid the need to remember with a subquery (hopefully someone will soon post a smaller and smarter answer):
SELECT users.* FROM users
JOIN (
SELECT userid, COUNT(*) as count
FROM posts
GROUP BY userid
) as subquery ON users.id = subquery.userid
ORDER BY subquery.count
Note: I haven't tested this query, but it looks good to me. Again: hopefully someone will post a better answer soon as I'm not doing my due dilligence, but you definitely need a JOIN :)
You could add a post_count column to the users table, but you would also have to update that count column every time a user creates a new post and you would have to build that logic into your application.
Otherwise, it looks like the answer from FallAndLearn will get you what you need.

Get user thanks count that is given by other users

I'm trying to build forum, but I need help about building MySQL query.
So my question - What MySQL query build should be to get user thanks count that is given by other users?
f_posts (table)
Columns:
- id
- user_id (post author)
f_thanks (table)
Columns:
- user_id (who give thanks)
- post_id
I tried to build query with FlySpeed SQL query builder and it looks:
SELECT p.id, p.user_id, k.id, k.post_id
FROM f_thanks k
LEFT JOIN f_posts p ON p.id = k.post_id
WHERE p.user_id = 15
Result (5 rows)
But it's not correct, because I have more than 5 thanks (should be atleast 10...)
SELECT count(*) FROM f_thanks WHERE user_id = 15
Result is 4 rows and it's correct, because I gave 4 thanks to other users.
(I've translated them: kiitused = thanks; postitused = posts; Estonian-English)
But I need to get user thanks count that is given by other users.
You are using left join. Then your where clause is turning it into an inner join, because of the NULL values produced by the left join.
The solution is to move the condition to the on clause:
SELECT p.id, p.user_id, k.id, k.post_id
FROM f_thanks k LEFT JOIN
f_posts p
ON p.id = k.post_id AND
p.user_id = 15;
When using left join, always put conditions on the second table into the on clause.

MySQL returning results from one table based on data in another table

Before delving into the issue, first I will explain the situation. I have two tables such as the following:
USERS TABLE
user_id
username
firstName
lastName
GROUPS TABLE
user_id
group_id
I want to retrieve all users who's first name is LIKE '%foo%' and who is a part of a group with group_id = 'givengid'
So, the query would like something like this:
SELECT user_id FROM users WHERE firstName LIKE '%foo'"
I can make a user defined sql function such as ismember(user_id, group_id) that will return 1 if the user is a part of the group and 0 if they are not and this to the WHERE clause in the aforementioned select statement. However, this means that for every user who's first name matches the criteria, another query has to be run through thousands of other records to find a potential match for a group entry.
The users and groups table will each have several hundred thousand records. Is it more conventional to use the user defined function approach or run a query using the UNION statement? If the UNION approach is best, what would the query with the union statement look like?
Of course, I will run benchmarks but I just want to get some perspective on the possible range of solutions for this situation and what is generally most effective/efficient.
You should use a JOIN to get users matching your two criteria.
SELECT
user_id
FROM
users
INNER JOIN
groups
ON groups.user_id = users.users_id
AND groups.group_id = given_id
WHERE
firstName LIKE '%foo'
You don't need to use either a UNION or a user-defined function here; instead, you can use a JOIN (which lets you join one table to another one based on a set of equivalent columns):
SELECT u.user_id
FROM users AS u
JOIN groups AS g
ON g.user_id = u.user_id
WHERE g.group_id = 'givengid'
AND u.firstName LIKE '%foo'
What this query does is join rows in the groups table to rows in the users table when the user_id is the same (so if you were to use SELECT *, you would end up with a long row containing the user data and the group data for that user). If multiple groups rows exist for the user, multiple rows will be retrieved before being filtered by the WHERE clause.
Use a join:
SELECT DISTINCT user_id
FROM users
INNER JOIN groups ON groups.user_id = users.user_id
WHERE users.firstName LIKE '%foo'
AND groups.group_id = '23'
The DISTINCT makes sure you don't have duplicate user IDs in the result.