Abit new to SQL (well this code anyhow) and somehow it doesn't seem to be wanting to return any results but has no SQL error, so I don't know where or what I'm doing wrong..
SELECT COUNT(`vote_counter`.`user_id`) AS count,
`vote_counter`.`user_id`,
`account_data`.`nickname`
FROM `vote_counter`
LEFT JOIN `account_data` ON `account_data`.`id` = `vote_counter`.`user_id`
WHERE `date` = 2017-02
GROUP BY `vote_counter`.`user_id`
ORDER BY count DESC
Account_date
table: puu.sh/tWrrZ/5121586f63.png I'm guessing this is probably something with my SQL, but not 100% sure. But it should return the count, user_id then grab the nickname from account_data and output it.
So, if user_id 1 has count as 5 and nickname "User 1" it would output the following : 5, 1, user 1
SELECT COUNT(`vote_counter`.`user_id`) AS count,
`vote_counter`.`user_id`,
`account_data`.`nickname`
FROM `vote_counter`
LEFT JOIN `account_data` ON `account_data`.`id` = `vote_counter`.`user_id`
WHERE `date` = 2017-02
GROUP BY `vote_counter`.`user_id`, `account_data`.`nickname`
ORDER BY count DESC
Count is directly stored in table. Why you are using aggregate function Count(vote_counter.user_id) as count to get that
select vote_counter.count,vote_counter.user_id
from vote_counter
LEFT JOIN account_data a ON a.id=vote_counter.user_id
where vote_counter.date=2017-02
group by vote_counter.user_id order by count
Try This One
SELECT COUNT(vote_counter.user_id) AS count,
vote_counter.user_id,
account_data.nickname
FROM vote_counter
LEFT JOIN account_data ON account_data.id = vote_counter.user_id
WHERE date = '2017-02'
GROUP BY vote_counter.user_i,
account_data.nickname
ORDER BY count DESC
After I finally worked out something that didn't look correct the final code that works is the following below. Thanks for the help!
SELECT vote_counter.count AS count,
vote_counter.user_id,
account_data.nickname
FROM vote_counter
LEFT JOIN account_data ON account_data.id = vote_counter.user_id
WHERE date = '2017-02'
GROUP BY vote_counter.user_id,
account_data.nickname
ORDER BY count DESC
The query you have in your answer, will NOT work. At least in SQL Server it will not work and produce an error. My assumption is in MySQL it will return results but the result will not be accurate results if duplicates were found: You do not have this scenario in your data right now but that does not mean you will never have it. Keep reading and you will see why.
There is a reason I asked in my comments you should read a tutorial on Group By
to really understand what is happening. There is no point in tweaking the query and waiting for results to show up and then conclude you have achieved what you need: You need to make sure the result is correct! More importantly you should know what your query is doing.
Consider this vote_counter
table (we will come back to naming later):
user_id count date
1 5 2016-08
1 NULL 2016-08
1 5 2017-02
2 5 2017-02
1 15 2017-02 <-- See this: user_id 1 has another entry for 2017-02
Your query is like this (I am omitting some parts for brevity):
SELECT vote_counter.count AS count,
vote_counter.user_id,
account_data.nickname
FROM ...
WHERE date = '2017-02'
GROUP BY vote_counter.user_id,
account_data.nickname
Will result in this error:
Msg 8120, Level 16, State 1, Line 1 Column 'vote_counter.count' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Let's say there was no error, the result of that query could be (I have added the last column to prove my point):
count user_id nickname date
5 1 Kasc 2017-02
15 1 Kasc 2017-02
5 2 Alzar 2017-02
So what is SQL server supposed to do now? You did a group by user_id
and nickname
, but user_id
with value 1 shows up twice so should it show 5 in the results or 15? I am not sure what MySQL will do in this case. Maybe it will show the sum of count or maybe it will show one record, I have no idea. But the confusion is there so it is better to be explicit and indicate what you want.
Almost Correct Query
So to get the correct results, you need to apply an aggregate function to instruct SQL Server to sum up the count
column. This should be the query (but this query is not good enough either, more later on this):
SELECT
SUM(vote_counter.count) AS [count], -- see the SUM aggregate
vote_counter.user_id,
account_data.nickname
FROM
vote_counter LEFT JOIN account_data ON account_data.id = vote_counter.user_id
WHERE
date = '2017-02'
GROUP BY
vote_counter.user_id,
account_data.nickname
ORDER BY
count DESC
Now the result will be:
count user_id nickname date
20 1 Kasc 2017-02
5 2 Alzar 2017-02
Ok that looks better.
How are NULL values treated in aggregate functions?
But what if you run the above query for date 2016-08
? You ask: what is so special about that date? Well that date has a Null
entry in the 2nd row for count. So what is the database engine going to do with a null entry. If you wrote this in SQL Server:
select Null + 1000000;
The result will be NULL
because NULL
plus any number is NULL
. So if we run our query for the vote count, will it show NULL
for the count
? No, it will not. It will show this result:
count user_id nickname date
5 1 Kasc 2016-08
But you will also see this message:
Warning: Null value is eliminated by an aggregate or other SET operation.
So in other words, the row with Null
value is totally eliminated and not considered by the the aggregate. Now you ask: So what is the problem? Well if you were doing another aggregate operation, such as Avg
, your results will be off and totally incorrect. Read this article for more details. Therefore, you should handle Null
values.
Correct Query
Here is the final and correct query (note the isnull
):
select
Sum(Isnull(vote_counter.count, 0)) as [count]
,vote_counter.user_id
,account_data.nickname
from
vote_counter
left join account_data
on account_data.id = vote_counter.user_id
where
date = '2017-02'
group by vote_counter.user_id
,account_data.nickname
order by count desc
In the above we are saying if the count
has NULL
, then use zero instead.
Table and Column Naming Conventions
I do not think naming a table vote_counter
is a good name because it sounds more like something that does counting. A better name would be vote_count
or better yet: VoteCount
using pascal notation (though some may not prefer it).
Try not using reserved keywords such as date
and count
to name your objects (tables, columns, indices etc.). So date
could be VoteDate
or VotingDate
and count
could be VoteCount
or NumberOfVotes
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.