How do I run a select query with count()? - mysql

account_users
-----
id | primary_key
posts
-----
post_id | primary_key
author | foreign key to account_users.id
Let's say I have 2 tables. account_users has the users. posts holds the posts.
How can I select all users where count(*) of posts are more than 5?

Try this
SELECT au.*,p.*
FROM account_users au
INNER JOIN posts p
ON p.account_users.id = au.id
GROUP BY p.post_id
HAVING count(*) > 5

#Timex
try below query.
Select au.ID from account_users au
inner join posts p on au.ID = p.author
Group By au.ID
having COUNT(p.post_id) > 5

Related

Phpmyadmin not selecting correct vaues

I am running this query in my database:
SELECT * FROM posts INNER JOIN profile ON posts.user_id = profile.user_id
WHERE posts.user_id IN
(SELECT user_id FROM users WHERE class_name IN
(SELECT class_name FROM classroom WHERE created_by = '456'))
OR posts.user_id IN
(SELECT user_id FROM users WHERE role = 'teacher' AND school_name = 'SK Taman Megah')
ORDER BY posts.created_at DESC;
This is my classroom table:
This is my users table:
This is my post table:
This is my profile table:
This is my output:
Expected output should have a total of 4 rows with post_id of (60,57,61,56) but only 2 was shown. Is there a mistake in the SQL query?
I think following one is what you are expecting:
SELECT * FROM posts INNER JOIN profile ON posts.user_id = profile.user_id where posts.user_id IN (select distinct user_id from users left join classroom on classroom.class_name = users.class_name where classroom.created_by='456' or (users.role='teacher' and users.school_name='SK Taman Megah') )

How do I add DESC to this query?

I'm doing a project and I'm using MYSQLI I just need to make this descend. How can I do this since the usual way on how I do this is not working.
SELECT * FROM posts
LEFT JOIN members ON posts.user_id = members.user_id
UNION
SELECT * FROM posts
RIGHT JOIN members ON posts.user_id = members.user_id
WHERE posts.user_id IS NOT NULL
This is what I tried
SELECT * FROM posts
LEFT JOIN members
ON posts.user_id = members.user_id
UNION
SELECT *
FROM posts
RIGHT JOIN members
ON posts.user_id = members.user_id
WHERE posts.user_id IS NOT NULL AND
ORDER BY posts.user_id DESC
IF you require ALL members with or without posts, then revers the table relationships so that the posts are left joined to members:
SELECT *
FROM members
INNER JOIN posts ON members.user_id = posts.user_id
ORDER BY members.user_id DESC, posts.id ASC ## I am guessing some column names
IF you have members with no posts AND posts with no members THEN you want the equivalent of a "full outer join" and this does require a UNION... although I seriously doubt the need for this here I include it for completeness:
SELECT * ## MUST choose the columns!!
FROM (
SELECT posts.*, members.* ## MUST choose the columns!!
FROM members
LEFT JOIN posts ON members.user_id = posts.user_id
UNION
SELECT posts.*, members.* ## MUST choose the columns!!
FROM posts
LEFT JOIN members ON posts.user_id = members.user_id
) d
ORDER BY user_id DESC, posts_id ASC ## I am guessing some column names
----
If you only require posts which have an associated user_id then I suggest you try this:
SELECT *
FROM posts
INNER JOIN members ON posts.user_id = members.user_id
ORDER BY members.user_id DESC, posts.id ASC ## I am guessing some column names
If you do need posts without a user_id then suggest you try this:
SELECT *
FROM posts
LEFT JOIN members ON posts.user_id = members.user_id
ORDER BY ISNULL(members.user_id) ASC, members.user_id DESC
The second part of your initial query will not add more rows to the final outcome. Consider the following test:
CREATE TABLE members
(`user_id` int);
INSERT INTO members
(`user_id`)
VALUES
(1);
CREATE TABLE posts
(`id` int, `user_id` int);
INSERT INTO posts
(`id`, `user_id`)
VALUES
(1, 1),
(2, NULL),
(3, NULL);
SELECT * FROM posts
LEFT JOIN members ON posts.user_id = members.user_id;
id | user_id | user_id
-: | ------: | ------:
1 | 1 | 1
2 | null | null
3 | null | null
SELECT * FROM posts
RIGHT JOIN members ON posts.user_id = members.user_id
WHERE posts.user_id IS NOT NULL;
id | user_id | user_id
-: | ------: | ------:
1 | 1 | 1
SELECT *
FROM posts
LEFT JOIN members ON posts.user_id = members.user_id
ORDER BY ISNULL(members.user_id) ASC, members.user_id DESC;
id | user_id | user_id
-: | ------: | ------:
1 | 1 | 1
2 | null | null
3 | null | null
dbfiddle here
Instead of using left and right join separately I would suggest you to use full outer join. And also remove the AND which is placed before ORDER.
So that your query will be like
SELECT * FROM POSTS FULL OUTER JOIN MEMBERS ON POSTS.user_id = MEMBERS.user_id
WHERE POSTS.user_id IS NOT NULL
ORDER BY POSTS.user_id DESC;

MySQL Left Join and excluding values

UPDATE
There is a database model in sqfiddle: http://sqlfiddle.com/#!2/8dbb0/10
And I updated the question according to the annotations.
Original Post
I have three tables:
posts
tags
tag_to_post
Lets asume a tag_id 1 that has been used by user 2. Now I want to show user 2 all posts, that another user has tagged with tag_id 1, but user 2 has not tagged with tag_id 1 so far.
The query:
SELECT posts.id AS post_id, tags.id AS tag_id, tag_to_post.user_id AS
user_tagged_post
FROM posts
LEFT JOIN tag_to_post ON tag_to_post.post_id = posts.id
LEFT JOIN tags ON tags.id = tag_to_post.tag_id
WHERE tags.id =1
Produces something like:
post_id | tags_id | user_tagged_post
1 | 1 | 1
1 | 1 | 2
2 | 1 | 2
3 | 1 | 1
So there should only be left post id 3.
First I tried with where-statement like:
WHERE tags.id = 1 AND tag_to_post.user_id != '2'
But this of course doesn't exclude post_id 1 cause it is a douplicate. I think there should be a DISTINCT or GROUPED BY before the WHERE clause, but this seems not to be allowed. So the only way is a sub-query? I didn't find a solution so far. Any ideas?
If I understand you correctly, it would seem like a straight forward LEFT JOIN;
SELECT t1.post_id, p.title, t1.tag_id, t1.user_id
FROM tag_to_post t1
JOIN posts p ON t1.post_id = p.id
LEFT JOIN tag_to_post t2
ON t1.tag_id = t2.tag_id AND t1.post_id = t2.post_id AND t2.user_id = 2
WHERE t1.user_id <> 2 AND t2.user_id IS NULL
An SQLfiddle to test with.
May be you need something like this
SELECT posts.id, posts.title, tags.tag, tag_to_post.user_id
FROM posts
INNER JOIN tag_to_post ON tag_to_post.post_id = posts.id
INNER JOIN tags ON tags.id = tag_to_post.tag_id
WHERE tags.id = 1 AND tag_to_post.user_id <> 2
Based on comments:
SELECT DISTINCT posts.id, posts.title, tags.tag, A.user_id
FROM posts
INNER JOIN tag_to_post A ON A.post_id = posts.id
INNER JOIN tags ON tags.id = A.tag_id
WHERE tags.id = 1
AND A.post_id NOT IN (SELECT post_id FROM tag_to_post WHERE tags.id = 1 AND user_id = 2)

Joining table issues

I have 3 tables that I'm looking to join:
pictures
--------
id user_id link
users
-----
id name
votes
-----
id user_id picture_id
Want I want to do is find the total number of votes for every picture for the specific user logged in. Pretty much I loop every picture out and if the user has votes on the picture they can't vote on it again.
Desired output:
---------------
id user_id link user_name total_votes
1 5 [link] Sean 5
So far I have something like this:
SELECT
p.*, u.username, d.total_votes
FROM pictures p
LEFT JOIN users u
ON p.user_id = u.id
LEFT JOIN
(
select id, picture_id, count(id) as has_voted from votes
) d on d.picture_id = p.id
I get all the pictures but all the votes are being added up on the first record.
EDIT
Sorry for being so unclear
So this is every image in my database. Say I'm logged in as Sean (user_id 1) I want to show how many times I votes on each image.
user_id is who uploaded the image.
(Updated) Try:
Select p.id, p.user_id, p.link, u.name, count(v.id) As total_votes
from pictures p
join users u on p.user_id = u.id
left join votes v on p.id = v.picture_id and v.user_id = ?
group by p.id
Try this
Select p.id, p.user_id, p.link, u.name,(CASE count(v.id) WHEN NULL THEN 0 ELSE count(v.id) END ) as total_votes
from pictures p
join users u on p.user_id = u.id
join votes v on (v.user_id = u.id and v.picture_id = p.id)
where v.id is not null
group by p.id

MySQL query with two INNER JOIN returns duplicate entries in the result

I have the following data structure: Articles have m:n Users
There are three tables: articles, users and articles_users (linking table)
Now I need this query: Give me all Users who have recently written an Article.
Unfortunately, this query returns duplicate results:
SELECT DISTINCT users.id,
users.username,
articles.published,
articles_users.user_id
FROM users
INNER JOIN articles_users
ON users.id = articles_users.user_id
INNER JOIN articles
ON articles.id = articles_users.article_id
ORDER BY articles.published DESC
LIMIT 25;
Result:
id username published user_id
113 silva_mihat 2012-10-30 112
228 paula_tille 2012-10-27 258
228 paula_tille 2012-10-26 258
631 andrea_gurkow 2012-10-24 631
275 hubert_mayer 2012-10-24 275
198 annette_mulger 2012-10-22 198
255 uta_zuffter 2012-10-22 235
and so on ...
Does anyone have an idea why DISTINCT isn't working here?
This should group by author instead of of by article.
select
users.id,
users.username,
maxPublished
from users
inner join (
select
max(articles.published) as maxPublished,
articles_users.user_id as userID
from articles
join articles_users on articles_users.article_id = articles.id
group by articles_users.user_id
) as p on users.id = userID
order by maxPublished desc
limit 25
;
because DISTINCT applies to the whole row (not just the users.id itself). as you can see all the rows returned are not unique. Try something like this, the idea behind the subquery is it gets the recent published date for each article_id
SELECT users.id,
users.username,
articles.published
FROM users
INNER JOIN articles_users
ON users.id = articles_users.user_id
INNER JOIN articles
ON articles.id = articles_users.article_id
INNER JOIN
(
SELECT id, MAX(published) maxDate
FROM articles
GROUP BY id
) c ON articles.id = c.ID AND
articles.published = c.maxDATE
-- ORDER BY articles.published DESC
-- LIMIT 25