My SQL Count( ) 0 with only 1 table - mysql

So I have seen this done with multiple tables, but am confused as to how this would work with multiple tables. I want to select the number of correct entries in a tournament. This works except if a user got none right. Then it returns NULL. I want this to return 0.
Table-tournament_entries
Column
=============
id
tournament_id
game_id
user_id
username
prediction
correct
Here is the query that I run, I am hoping to return all users even the ones who did not get any questions right.
SELECT
tournament_id, username, user_id, COUNT(`prediction`)
FROM
tournament_entries
WHERE
correct = 1 AND tournament_id = 1
GROUP BY
username
ORDER BY
COUNT(`prediction`) DESC
LIMIT 0,10
EDIT: Sorry for all the confusion so when I run my query I get this
username user_id CorrectAns
mj 455 10
charlie 1 8
bill 2 8
doug 51 7
but there are users who are not show who have received 0 right. When I run the queries suggested I receive the number of questions .
username user_id CorrectAns
mj 455 16
charlie 1 16
bill 2 16
doug 51 16
sydney 452 16
Joe 218 16
If you notice sydney and joe are not in the first output but are in the second one

Use this query:
$query ="SELECT tournament_id, username, user_id, COALESCE(COUNT(`prediction`),0) as cpred
FROM tournament_entries
WHERE tournament_id = 1
GROUP BY username
ORDER BY cpred DESC
LIMIT 0,10"
COALESCE will return the first non-null parameter given to it.
Cheers.

Based on your comments to the other answer, I think what you're actually looking for is something like this (although it's hard to be sure without sample data and output):
SELECT
username, user_id, Sum(correct) As TotalCorrect
FROM
tournament_entries
WHERE
tournament_id = 1
GROUP BY
username, user_id
ORDER BY
TotalCorrect DESC
LIMIT 0,10

Related

MySQL DISTINCT call counts by state

I'm trying to get the unique call counts (no dupe calls) by state. For example...
MO 249
OK 220
CA 216
TX 190
KS 158
The following works (no errors), but it's not removing the dupes.
SELECT DISTINCT CallFrom, FromState, count(*) AS cnt
FROM `calls`
WHERE DateCreated >= CURDATE() - INTERVAL 2 YEAR AND
(CallTo = '+15555555555' OR CallTo = '+15555555556' )
GROUP BY FromState
ORDER BY cnt DESC
Any ideas? Thanks in advance.
UPDATE: The following 'calls' table example was requested...
Index CallTo CallFrom FromState
1 +15555555555 18166283100 MO
2 +15555555556 13307059600 OH
3 +15555555555 17722631600 FL
4 +15555555556 16173024800 MA
5 +15555555556 16173024800 MA
6 +15555555556 16175025500 MA
Just realized I forgot to include the DateCreated column, but like I said, everything is working except for deduplicating. The output for this example would be...
MA 2
MO 1
OH 1
FL 1
Your wording is not very clear, but I think you're saying you want to count how many unique CallFrom numbers occurred in each state. There may be better ways to do this, but this will work. First it builds a list of unique CallFrom/State combinations, and then it groups and counts on that list, instead of on the raw data:
SELECT FromState, COUNT(*)
FROM
(SELECT DISTINCT CallFrom, FromState
FROM `calls`
WHERE
(CallTo = '+15555555555' OR CallTo = '+15555555556' )
) c
GROUP BY FromState
Demo:
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=d057e3482ec9d5ad4519e58056232e58

Sql select where a column has been set atleast once

I have this table
**applications**
id user_id company_id shortlisted
1 10 99 0
2 10 100 1
3 10 101 1
4 10 102 0
5 11 99 1
6 12 99 0
6 12 101 0
What I want is to select all users
which have been shortlisted at-least once
which have not been shortlisted at all
For the first case, i have the following query:
SELECT user_id
from applications
where shortlisted=1
Group
By user_id
and this gives me the expected result like below
**applications**
user_id
10
11
But I'm trying the following query for the second case and it returns me an empty set:
Select user_id
from applications as Application
where shortlisted=0
and NOT EXISTS(Select user_id from applications where user_id=Application.user_id and shortlisted=1)
What am i missing?
PS: Please ignore any typos as i typed them manually for this post.
To get both results in a single query simply use aggregation:
select user_id, max(shortlisted) as was_shortlisted
from applications
group By user_id
You can use group by and having for both.
For the first:
select user_id
from applications
group By user_id
having max(shortlisted) = 1;
For the second:
select user_id
from applications
group By user_id
having max(shortlisted) = 0;
In all honesty, your version with the where is more efficient for the first query. This is just to show how closely related the queries are.
You can try following query;
select user_id from table1
group by user_id having MIN(shortlisted) = 1
This will give you to at least have shortlisted = 1 condition and don't have shortlisted = 0 records.

SQL query to sort table by sum

I have basically following table:
id (int) username (string) messsage (string) rating (int)
So the entries look like this:
1 thomas "hello..." 3
2 Tina "blabla" 2
3 thomas "blub" 1
4 julia "basgs" 3
...
I want retrieve the top 10 usernames with the most ratings for all their messages.
So I want to sort the table that it looks
1. thomas 4
2. julia 3
3. Tina 2
I'm not sue I understood your question right, but try that one:
SELECT
username,
SUM(rating)
FROM
YourTable
GROUP BY
username
ORDER BY
SUM(rating) desc
LIMIT
10
select username
, count(*)
from YourTable
group by
username
order by
count(*) desc
limit 10

MYSQL sum of item purchases and its 'up'/'down' votes are multiplied by a factor of 22?

I'm trying to count the number of purchases and 'up'/'down' votes for all items that match a given search term. Unfortunately, as I've set up my query now, the purchases and vote counts are multiplied by a mysterious factor of 22 that I can not figure out where it comes from.
As an example for one of the items: the purchases, up, and down votes should be 7, 2, and 1 respectively but they are instead 154, 44, and 22.
here's my SQL code:
SELECT *
sum(purchaseyesno) as tots,
sum(rating=1) as yes,
sum(rating=0) as no
from items
join items_purchased
on items_purchased.item_id=items.item_id
join accounts
on items.account_id=accounts.account_id
like subject='%album by joe%' or description='%album by joe%'
group by item_id
order by tots desc, yes desc
Here's some sample data:
subject tots yes no full_name
album by joe 154 44 22 joe smith
album by fred 88 44 0 fred jones
Here's how i'd like the data to look:
subject tots yes no full_name
album by joe 7 2 1 joe smith
album by fred 4 2 0 fred jones
Would someone be able to help me figure out what is going on here? I can't figure out this factor of 22 issue which persists despite changing the group by and other things (meaning, this 22 number is independent of the # of returned rows).
You don't show your schema but it might help to use a subquery:
SELECT subject, tots, yes, no, fullnane
FROM (
SELECT item_id, SUM(purchaseyesno) AS tots, SUM(rating=1) AS yes, SUM(rating=0) AS no
FROM items_purchased
GROUP BY item_id
) i
JOIN items ON i.item_id = items.item_id
JOIN accounts ON items.account_id=accounts.account_id
WHERE subject LIKE '%album by joe%' OR description LIKE '%album by joe%'
ORDER BY tots DESC, yes DESC
Firstly, don't do select * if you're grouping by. Remember you must group by all non-aggregated fields.
Secondly, the high amount of results must be comming from those joins. Remove the group by and the aggregated columns and inspect the results and you'll see why you're getting so many records.
Finally... you're missing a where clause there...
SELECT subject,
sum(purchaseyesno)/22 as tots,
sum(CASE WHEN rating=1 THEN 1 END)/22 as yes,
sum(CASE WHEN rating=0 THEN 1 END)/22 as no,
full_name
from items
join items_purchased
on items_purchased.item_id=items.item_id
join accounts
on items.account_id=accounts.account_id
like subject='%album by joe%' or description='%album by joe%'
group by subject,full_name
order by tots desc, yes desc
In this query,the SUM function basically works on the columns purchaseyesno,rating=1,rating=0.
For eg.
Subject purchaseyesno rating full_name
1 5 1 Mark
1 6 0 Mark
2 7 1 Robert
2 8 0 Robert
The above query will return as below.
Subject tots yes no full_name
1 11 1 1 Mark
2 15 1 1 Robert

MySQL Query matching multiple fields

I have a database that has a table that has different LIKES that people have. Each like is stored as a different record. The only info I have in each record is userID, likeID.
The search will be based on the current userID that is signed in. So I'm not matching EVERYONE with EVERYONE but instead matching EVERYONE vs 1
So userID 45 might have likeID 3, likeID 6 and likeID 22 in the table (for instance)
What I want to do is have the table return, in descending order userIDs that they match with based on the total likes they match with someone else.
For example, (based on user 45 example above) it would look at userID 1 and see how many of likeID 3, likeID 6 and likeID 22 they have. then it'd go to userID 2 and see how many of likeID 3, likeID 6 and likeID 22 they have.....it'd do this for everyone.
Then it'd show the results for any that have more than 0 matches for those 3 likeIDs:
Matches:
You and UserID 12 share 3 of the same likes.
You and UserID 87 share 3 of the same likes.
You and UserID 22 share 2 of the same likes.
You and UserID 73 share 2 of the smae likes.
You and UserID 71 share 1 of the same likes.
etc...
I hope that explains what I'm trying to do. I don't think the mySQL query will be too hard but right now I'm baffled at how to do it!
THANKS IN ADVANCE!
select
UL2.userID,
count(*) as LikeMatches
from
UserLikes UL1
JOIN UserLikes UL2
on UL1.LikeID = UL2.LikeID
AND UL1.UserID != SingleUserBasisParameter
where
UL1.UserID = SingleUserBasisParameter
group by
UL2.UserID
order by
2 desc
The "2" in the order by is the ordinal column representing the COUNT(*)
select userid,count(*) as common_likes
from table
where likeid in (select likeid from table where userid = 45) and userid <> 45
group by userid
order by common_likes desc
how about:
SELECT COUNT(likes.likeID) as like_count FROM
LIKES as likes,
(SELECT UserID,likeID FROM likes WHERE UserID = $user_id) as user_likes
WHERE
user_likes.likeID = likes.likeID AND user_likes.userID != likes.userID
GROUP BY likes.UserID
ORDER BY like_count
I haven't tested it, but I think that it should at least give you the right idea. The 2nd SELECT finds all the likes of the main user, which you can then use to filter out the other likes.