I am trying to run this query
SELECT a.id, count (*) as MovieCount
FROM actors a
JOIN roles r ON a.id = r.actor_id
GROUP BY a.id
but it underlines my * in red and says Error 1064. What could be wrong about the star in parentheses?
The problem (as explained in a comment and deleted answer) is the space after count.
However, you should be aware that you can significantly simplify the query by removing the join:
SELECT r.actor_id, count(*) as MovieCount
FROM roles r
GROUP BY r.actor_id
Related
Firstly, I'm a beginner to MySQL and I'm still learning. I'm trying to join 2 tables to display a count. Primarily, I use 2 codes. One code to display names -
SELECT tag_logs.timestamp, People.Name FROM `tag_logs` INNER JOIN People WHERE tag_logs.tag_no = People.nametag
Another code to display count of names -
SELECT tag_logs.tag_no, COUNT(tag_logs.tag_no) FROM tag_logs GROUP BY tag_no HAVING COUNT(tag_no) >= 1
I want to display Name and a count number, instead of a tag number and count. I attempted to join both tables by using the following code, however, I've had little luck -
SELECT People.Name FROM `tag_logs` INNER JOIN People WHERE tag_logs.tag_no = People.nametag AND COUNT(tag_logs.tag_no) FROM tag_logs GROUP BY tag_no HAVING COUNT(tag_no) >= 1
I'm given an error when I try to call 'FROM tag_logs' a second time. Is there a way to work around this?
I aim to make this my final result, except I should be able to see names instead of numbers.
Two tables are joined using ON clause. You should learn joins.
SELECT People.Name ,COUNT(tag_logs.tag_no)
FROM `tag_logs`
INNER JOIN People ON tag_logs.tag_no = People.nametag
GROUP BY tag_logs.tag_no
HAVING COUNT(tag_no) >= 1
It should be
SELECT People.Name FROM `tag_logs`
INNER JOIN People on tag_logs.tag_no = People.nametag
GROUP BY tag_no HAVING COUNT(tag_no) >= 1
EDIT
SELECT People.Name, COUNT(tag_no) FROM `tag_logs`
INNER JOIN People on tag_logs.tag_no = People.nametag
GROUP BY tag_no HAVING COUNT(tag_no) >= 1
I believe the query that you want looks like this:
SELECT p.Name, COUNT(*)
FROM tag_logs tl INNER JOIN
People p
ON tl.tag_no = p.nametag
GROUP BY p.Name;
Notes:
COUNT(*) is shorter than COUNT(tl.tag_no) and they do the same thing.
GROUP BY clause now matches the SELECT. If you could have people with the same names, then add p.nametag to the GROUP BY. A version use only GROUP BY tl.tag_no is invalid SQL and should fail in most databases, because of the non-matching p.Name in the SELECT.
The HAVING clause (HAVING COUNT(tag_no) >= 1) is unnecessary, because the INNER JOIN requires at least one match and tag_no is never NULL (because it is used for the JOIN).
I introduced table aliases, so the query is easier to write and to read.
So I'm kinda new to SQL joins and was thinking on going full overkill probably.
What I want to do is join my four tables together.
What I want to accomplish is that I want all the information from category, and I want it to be matched to the replies with the newest timestamp and then I want to join the t.title which t.id matches r.thread_id
SELECT c.*, t.id, t.title, r.timestamp, u.id, u.username
FROM forum_category AS c
LEFT JOIN forum_threads AS t ON (c.id = t.category_id)
LEFT JOIN forum_replies AS r ON (t.id = r.thread_id
AND r.timestamp =
(
SELECT timestamp
FROM forum_replies
ORDER BY timestamp DESC LIMIT 1
))
LEFT JOIN users AS u ON (r.user_id = u.id)
GROUP BY c.id
As it is now this code seems to work, not having tested it alot.
However I need to expand it to check if t.timestamp is newer than latest r.timestamp and JOIN that one instead then. with the t.title, t.timestamp and t.user_id.
So if a thread is newer than the latest reply.
I know I could make the first post a reply and solve it that way. But I'm not doing that right now if it's possible to solve in the SQL statement.
SQL layout imgur here:
https://imgur.com/a/nCn2a
forum_category:
forum_threads:
forum_replies:
One helpful technique is to use Subqueries to break up the mental logic of what your query is trying to do. Basically, a subquery takes the place of a regular table in any query.
So, first up, we need to get the most recent time stamp in the replies for each thread:
select thread_id, max(timestamp) as LatestReply
from forum_replies
group by thread_id
Let's call this our MostRecentThreadSubquery. So, it would let us do something like:
select * from
forum_threads t
LEFT JOIN
(
select thread_id, max(timestamp) as LatestReply
from forum_replies
group by thread_id
) as MostRecentThreadSubquery
on t.thread_id = MostRecentThreadSubquery.thread_id
Make sense? We're no longer joining the forum_threads table against the forum_replies table - we've made a subquery to help us list the most recent reply for each thread id.
Now, we add the SQL CASE statement, to get something like:
select
thread_id,
CASE WHEN t.timestamp > MostRecentThreadSubquery.LatestReply
THEN t.timestamp
ELSE MostRecentThreadSubquery.LatestReply
END as MostRecentTimestamp
from -- ... the rest of that earlier SQL statement
Okay, so now we've got a query that, for every thread_id, has the most recent timestamp - whether that's from the forum_replies or from the forum_threads table.
... and you guessed it. We're going to make it another subquery. Let's call it our MostRecentPerThread
select *
from forum_category AS c
LEFT JOIN
(
-- ... that previous query ...
) as MostRecentPerThread
on c.thread_id = MostRecentPerThread.thread_id
Make sense? You're using subqueries as a way of logically breaking down your query into smaller components. You no longer have one gigantic query. You've got a small subquery that simply gets the timestamp of the most recent reply. You've got a small subquery that compares that first subquery to the threads table to get the most recent timestamp. And you've got a main query that uses the second subquery to merge it with the categories table.
It works but what I would like is to list username, first name, last name not all but I've tried JOIN and isn't seeming to work. Any ideas? Thanks!
MY DB:
http://gyazo.com/eb13cd68440d20719ce0783018cb9828
SELECT
M.Username,
M.first_name,
M.Last_name,
COUNT(1) AS num_comments
FROM members AS M
INNER JOIN comments AS C
ON C.memberID = M.memberID
GROUP BY
C.memberID
ORDER BY COUNT(1) DESC
LIMIT 1
This matches the Member to all their comments, groups by the member to get the count of comments for the users, orders by the count starting highest first, then returns the first result.
Instead of selecting * (ALL) just use SELECT table.username, table.firstname, table.lastname [...].
You can leave out the table. if all information is stored in your comments table. If not, adjust accordingly. In that case you'll also need to Join the comments table with the table where the rest of the information is stored.
Edit:
SELECT m.username, m.first_name, m.last_name FROM members m, comments c WHERE m.MemberID = c.MemberID AND c.author = (select max(author) from comments)
Need to generate courses list and count
all
unanswered
answered but unchecked
Questions.
My database structure is looking like that
https://docs.google.com/open?id=0B9ExyO6ktYcOenZ1WlBwdlY2R3c
Explanation for some of tables:
answer_chk_results - checked answers table. So if some answer doesn't exist on this table, it means it's unchecked
lesson_questions - lesson <-> question associations (by id) table
courses-lessons - courses <-> lessons associations (by id) table
Executing
SELECT
c.ID,
c. NAME,
COUNT(lq.id) AS Questions,
COUNT(
CASE
WHEN a.id IS NULL THEN
lq.id
END
) AS UnAnswered,
COUNT(
CASE
WHEN cr.id IS NULL THEN
lq.id
END
) AS UnChecked
FROM
courses c
LEFT JOIN `courses-lessons` cl ON cl.cid = c.id
LEFT JOIN `lesson_questions` lq ON lq.lid = cl.lid
LEFT JOIN answers a ON a.qid = lq.qid
LEFT JOIN answer_chk_results cr ON cr.aid = a.id
GROUP BY
c.ID
Tested it first on SQL fiddle with sample data. (Real data is huge, so I can't place it on sqlfiddle) It returned some values. Thought works well. But while I test it with real data, see that returns wrong values. Forex, when I manually count, result for all questions count must be 25, but it returns 27. Maybe I'm doing something wrong.
Note MySQL server running on my local machine, so I can give you teamviewer id and password if you want to connect to my desktop remotely and test query with real data.
I suspect the problem is that different joins are resulting in a multiplication of rows. The best way to fix this is by using subqueries along each dimension. The following is a more practical way. Replace the COUNTs in the select with COUNT DISTINCT:
SELECT c.ID, c. NAME,
COUNT(distinct lq.id) AS Questions,
COUNT(distinct CASE WHEN a.id IS NULL THEN lq.id END) AS UnAnswered,
COUNT(distinct CASE WHEN cr.id IS NULL THEN lq.id END) AS UnChecked
Compared to COUNT, COUNT DISTINCT is a resource hog (it has to remove duplicates). However, it will probably work fine for your purposes.
Use this query
SELECT
c.ID,
c.NAME,
COUNT(lq.id) AS Questions,
COUNT(IFNULL(a.id),lq.id)AS UnAnswered,
COUNT(IFNULL(cr.id),lq.id)AS UnChecked,
FROM courses c
LEFT JOIN `courses-lessons` cl ON cl.cid = c.id
LEFT JOIN `lesson_questions` AS lq ON lq.lid = cl.lid
LEFT JOIN answers a ON a.qid = lq.qid
LEFT JOIN answer_chk_results cr ON cr.aid = a.id
GROUP BY c.ID
I have a mysql DB with two tables:
messages
message_answers
I'd like to fetch all messages and the number of answers for each of them, like:
first message (10 answers)
second message (5 answers)
Is it possible with a single sql query ?
I tried a query and a subquery for the count, but I don't know how to have the current id from the main query to make the "WHERE" restriction on the subquery (like: "message_answers.message_id = messages.id").
Thank you,
Sébastien
SELECT m.message, COUNT(ma.answer_id) AS AnswerCount
FROM messages m
LEFT JOIN message_answers ma
ON m.id = ma.message_id
GROUP BY m.message
select m.id, count(ma.id)
from messages m
join join message_answer ma on ma.id = m.message_id
group by 1