简体   繁体   中英

SQL not returning any results?

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

在此输入图像描述

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM