Using Rollup in Mysql - mysql

I'm having trouble using rollup in mysql. I want a table that looks something like this:
Person | Count
John | 3
Sam | 2
Total | 5
The code I wrote:
SELECT person, count(*), IFNULL(count(*),"Total") AS Count FROM ProductsSold GROUP BY
person WITH ROLLUP;
But Instead total is staying null and all my counts say BLOB in workbench.

My guess is you want to rename the person NULL which holds the ROLLUP result to Total. That means you have do your IFNULL construct on the person column:
SELECT IFNULL(person,"Total") as person, count(*) AS Count
FROM ProductsSold
GROUP BY person WITH ROLLUP
makes:
John 3
Sam 2
Total 5

Related

Need validation that interpretation for a Grouping Query is correct

I am running the following query and at first it appears to give the sub totals for customers and shows by date each customers payment amounts only if that total for all payments is greater than $90,000.
SELECT
Customername,
Date(paymentDate),
CONCAT('$', Round(SUM(amount),2)) AS 'High $ Paying Customers'
FROM Payments
JOIN Customers
On payments.customernumber = customers.customernumber
Group by customername, Date(paymentDate) WITH ROLLUP
having sum(amount)> 90000;
But upon looking at the records for Dragon Souveniers, Ltd. and Euro+ Shopping Channel is is actually showing the paydates that have amounts individually over $90000 as well as the subtotal for that customer as a rollup. For all other customers, their individual payment dates are not reported in the result set and only their sum is if it over $90000. For example Annna's Decorations as 4 payment records and none of them are over 90000 but her sum is reported as the value for the total payments in the query with the rollup. Is this the correct interpretation?
The HAVING clause work correct, It filters all records with a total no above 90000. It also does do this for totals.
When using GROUP BY .... WITH ROLLUP, you can detect the created ROLL UP lines by using the GROUPING() function.
You should add a condition in a way that the desired columns are not filtered.
Simple example:
select a, sum(a), grouping(a<3)
from (select 1 as a
union
select 2
union select 3) x
group by a<3 with rollup;
output:
+---+--------+---------------+
| a | sum(a) | grouping(a<3) |
+---+--------+---------------+
| 3 | 3 | 0 |
| 1 | 3 | 0 |
| 1 | 6 | 1 |
+---+--------+---------------+
this shows that the last line (with grouping(i<3) == 1) is a line containing totals for a<3.

Query to get distinct count of column with MYSQL

I have a table name POEMS with columns poemID and userID. I want to make the poemID distinct and show only the count in the userID column. There are 3 poemID's with 1. I want to make it show poemID 1 and userID would be 2. poemID 2 and userID 3, for the 3 rows and poemID 3 with userID 1 for the 1 row.
|poemID | userID|
1 1
1 5
2 2
2 5
2 4
3 2
I want the above table to look like the table below.
|poemID | userID |
1 2
2 3
3 1
My SQL query im trying is below but its not working. Please help.
SELECT DISTINCT(poemID), COUNT(userID) FROM POEMS GROUP BY poemID;
This looks like a straight aggregation query:
SELECT poemID, COUNT(*) no_users
FROM POEMS
GROUP BY poemID;
Or, if the same user may appear multiple times for a given poem and you want to count it only once:
SELECT poemID, COUNT(DISTINCT userID) no_distinct_users
FROM POEMS
GROUP BY poemID;

mysql how to use column count when same column can have 2 different values

I have an cutomer table where i store some customer error data
I would like to find different count on the same column.
Errorid custName ErrorReported
----------------------------------
1 abc Dead_battery
2 xyz Low_voltage
3 ann Dead_battery
4 ben Dead_battery
5 max Low_voltage
The result of sql query should be count and ErrorReportedtype
count(*) Errortype
------------------------
3 Dead_battery
2 Low_voltage
If you group by the column to be unique you can use aggregate functions like count on every group
select count(*), ErrorReported as ErrorType
from your_table
group by ErrorReported

Multiple SUM commands

I am trying to sum a column in my table, the problem being there are multiple sums that need to be done.
So for instance there may be 40 records with an ID of 1 and a point value of 20, And then it will change to a new person with an ID of 2 and a point value of 20. If that makes sense.
How I want to do the query, but it doesn't work is like this:
SELECT SUM(Value)
FROM Points WHERE RegNum IN('','','')
And then I would like it to show up just like a normal SUM command would, with the total summed up, but with a line for each ID. I have looked over other questions about SUM commands and just can't quite apply it to my situation.
Thank you for any help.
It seems like you need to use a GROUP BY in your case. Try
SELECT RegNum, SUM(Value) total
FROM Points
WHERE RegNum IN(1, 2, 3)
GROUP BY RegNum
Sample output:
| REGNUM | TOTAL |
------------------
| 1 | 17 |
| 2 | 9 |
| 3 | 1 |
Here is SQLFiddle demo
Try
SELECT RegNum, SUM(Value) as TotalRegNum
From Points
WHERE RegNum IN('1','2','3')
GROUP BY RegNum

Is it possible to perform calculations with mysql?

I have a DB table for photo ratings and want to retrieve the highest rated photos. I know I need to do this based on an average for the ratings sorted from highest to lowest. The DB table looks like this:
id rating rated_photo_id
-- ------ -------------
1 5 1
2 6 1
3 3 2
4 4 1
5 7 2
Is it efficient or even possible to perform this calculation in the SQL query? If not would it make sense to maintain a second table that stores the averages for each photo_id?
This is possible with almost all databases. Check out the aggregate functions of MySQL.
http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html
Specifically http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_avg for your question.
You DO NOT need a second table. The rating table has the information you need. Use MySQL aggregate functions with GROUP BY:
SELECT rated_photo_id, AVG(rating) AS AverageRating, COUNT(*) AS NumberOfRatings
FROM rating_table
GROUP BY rated_photo_id
ORDER BY AverageRating DESC
Output:
+----------------+---------------+-----------------+
| rated_photo_id | AverageRating | NumberOfRatings |
+----------------+---------------+-----------------+
| 1 | 5.0000 | 3 |
| 2 | 5.0000 | 2 |
+----------------+---------------+-----------------+
Yes, it's easy and efficient to calculate averages, assuming you've an index on the rated_photo_id column
select rated_photo_id, AVG(rating) as average_rating
from photos group by rated_photo_id order by average_rating desc
For a specific photo could specify an id:
select rated_photo_id, AVG(rating)
from photos where rated_photo_id = 2 group by rated_photo_id
Ideally your index would be (rated_photo_id, rating) to be covering for these queries--resulting in the fastest execution.
You should be able to just group by the photo id and get the average as the group is created.
SELECT rated_photo_id , AVG(rating) as rating
FROM photos
GROUP BY rated_photo_id
ORDER BY rating DESC