Sum up the count - postgresql

I have a table like this:
Count Product
100 apple
50 apple
20 orange
How can I select to get the sum of the count per product like this?
Count Product
150 apple
20 orange

Try Query using SUM(),
select SUM(count) as count,Product from #YourTable
group by Product
SUM() function returns the total sum of a numeric column

You should use Aggregate Functions :
select SUM(count) as Count, Product from Product
group by Product

Related

How can I display the top 5 artists by sum of play count for each year?

I am working on a project using my daily music listens data from Apple Music from 2018-2022. The table daily_listens consists of the following columns shown in this example:
track_identifier
date_played
year_played
play_duration
source_type
play_count
skip_count
track_reference
track_description
artist
song
1127435215
20180410
2018
1102507
IPHONE
6
3
1127435215
Mos Def - Auditorium (feat. Slick Rick)
Mos Def
Auditorium (feat. Slick Rick)
I am using the columns year_played, play_count and artist in this scenario. play_count is listed for each song so I want to rank each of the artists by the sum of their play_counts and rank the top 5 for each year. I am trying to get a result similar to this example below.
This is what I have got so far. It gives me the list of all artists with their total play count for each year. However I cannot figure out how to rank them from highest to lowest and limit it to 5 results for each year.
SELECT RANK() OVER(PARTITION BY year_played ORDER BY total_listens_per_artist) AS ranks,
*
FROM (
SELECT DISTINCT artist,
year_played,
SUM(play_count) OVER(PARTITION BY artist) AS counts
FROM daily_listens
) AS total_listens_per_artist;
Thank you and please let me know if you need any additional information.
WITH play_count AS (
SELECT
artist,
SUM(play_count) AS counts
FROM daily_listens
GROUP BY artist
)
SELECT *
FROM play_count
ORDER BY counts
LIMIT 5

Calculating ratios in postgresql

I new to postgresql and I am trying do calculate a rate in a table like this:
class phase
a sold
b stock
c idle
d sold
I want to calculate the total count of sold phases / total like this:
2/4 = 50%
i was trying:
with t as ( select count(class) as total_sold from table where phase='sold')
select total_sold / count(*) from t
group by total_sold
but the result is wrong. How can I do this?
Use AVG() aggregate function:
SELECT 100 * AVG((phase = 'sold')::int) AS avg_sold
FROM tablename;
The boolean expression phase = 'sold' is converted to an integer 1 for true or 0 for false and the average of these values is the ratio that you want.
See the demo.

SQL to select users into groups based on group percentage

To keep this simple, let's say I have a table with 100 records that include:
userId
pointsEarned
I would like to group these 100 records (or whatever the total is based on other criteria) into several groups as follows:
Group 1, 15% of total records
Group 2, 25% of total records
Group 3, 10% of total records
Group 4, 10% of total records
Group 5, 40% (remaining of total records, percentage doesn't really matter)
In addition to the above, there will be a minimum of 3 groups and a maximum of 5 groups with varying percentages that always totally 100%. If it makes it easier, the last group will always be the remainder not picked in the other groups.
I'd like to results to be as follows:
groupNbr
userId
pointsEarned
To do this sort of breakup, you need a way to rank the records so that you can decide which group they belong in. If you do not want to randomise the group allocation, and userId is contiguous number, then using userId would be sufficient. However, you probably can't guarantee that, so you need to create some sort of ranking, then use that to split your data into groups. Here is a simple example.
Declare #Total int
Set #Total = Select COUNT(*) from dataTable
Select case
when ranking <= 0.15 * #Total then 1
when ranking <= 0.4 * #Total then 2
when ranking <= 0.5 * #Total then 3
when ranking <= 0.6 * #Total then 4
else 5 end as groupNbr,
userId,
pointsEearned
FROM (Select userId, pointsEarned, ROW_NUMBER() OVER (ORDER BY userId) as ranking From dataTable) A
If you need to randomise which group data end up in, then you need to allocate a random number to each row first, and then rank them by that random number and then split as above.
If you need to make the splits more flexible, you could design a split table that has columns like minPercentage, maxPercentage, groupNbr, fill it with the splits and do something like this
Declare #Total int
Set #Total = Select COUNT(*) from dataTable
Select S.groupNbr
B.userId,
B.pointsEearned
FROM (Select ranking / #Total * 100 as rankPercent, userId, pointsEarned
FROM (Select userId, pointsEarned, ROW_NUMBER() OVER (ORDER BY userId) as ranking From dataTable) A
) B
inner join splitTable S on S.minPercentage <= rankPercent and S.maxPercentage >= rankPercent

Calculating sum of a column in a dataset

I have the following query for a dataset:
select item, sum(salesAmount) as TotalSales from sales
group by item
order by TotalSales desc;
and I have set REPORT_COUNT<=5 for limiting the data to 5 records only.
Now I want to display top 5 items through a list component and their Sales Amount in percentage to that of the TotalSales amount of the top 5 items.
I have tried to create a variable in the dataset as
sales_sum
class: BigDecimal
Calculation : Sum
Reset Type : Report
Increment Type : None
Variable Expression : $F{TotalSales}
But the sales_sum increments with each row in the list. thus gives inaccurate value
for the percentage. What should I do?
It is because of the evaluation time of sales_sum variable , as I understand this variable is calculating sum row wise i.e for first row sum will be same as TotalSales value then for second row sum will be first value of and second value of TotalSales and so on, so you will be getting 1st % always 100.
To change this Evaluation Time property select the field where you are using sales_sum variable like for sales percentage and go to the property of that field and change the Evaluation Time property to :-
Evaluation Time Auto
Second solution:-
SELECT a.item,a.TotalSales, (a.TotalSales/a.Total) * 100 as Total_Perc
FROM
(select item,
sum(salesAmount) as TotalSales,
(select sum(salesAmount) as TotalSales from sales
order by TotalSales desc
limit 5) Total
from sales
group by item
order by TotalSales desc
limit 5) a;

Get total count per ID change

how can I get a total count of sheets per change of sheet
example:
select sheetID,
..
from SomeTable
results look something like this:
sheetID
-----------
1000
1000
1000
1000
3000
3000
3000
so I want something like this:
select sheetID,
count(sheetID) as TotalsheetCount
from SomeTable
I just don't know how to break the count up per change of sheetID.
So I'd end up with this essentially:
sheetID TotalsheetCount
-------- -----------
1000 4
1000 4
1000 4
1000 4
3000 3
3000 3
3000 3
so 4 is because there are 4 1000s, 3 because there are 3 3000s. I am wanting to repeat the total count for that sheetID for each row, even though it's repeating, I want to provide that.
UPDATE, here's what I did per the replies but I'm getting way too many results now as compoared to the count where I did not add that partition count before
select MainTable.sheetID,
COUNT(SomeTable.sheetID)OVER(PARTITION BY SomeTable.sheetID) AS TotalSheetCount
table2.SomeField1,
table2.SomeField1
from MainTable
join (select distinct Sales.SalesKey from SomeLongTableName_Sales) sales on sales.SheetKey = MainTable.sheetKey
left outer join Site on MainTable.SiteKey = Site.SiteKey
join Calendar on sales.Date >= Calendar.StartDate
and sales.Date < Calendar.EndDate
group by SomeTable.sheetID
the joins and stuff is more realistic to my real query but formatted for this post to hide real field and table names.
You probably want to use a GROUP BY:
SELECT sheetID, COUNT(sheetID) AS TotalsheetCount
FROM dbo.SomeTable
GROUP BY sheetID
I am wanting to repeat the total count for that sheetID for each row,
even though it's repeating, I want to provide that
If you're using at least SQL-Server 2005, you can use a CTE with COUNT + OVER-clause, otherwise use a sub-query:
WITH CTE AS
(
SELECT sheetID,
COUNT(sheetID)OVER(PARTITION BY sheetID) AS TotalsheetCount
FROM SomeTable
)
SELECT sheetID, TotalsheetCount FROM CTE
Use the GROUP BY clause in a subquery to select the counts:
SELECT sheetID,
count(sheetID) as TotalsheetCount
FROM SomeTable
GROUP BY sheetID
This would make your whole query look like this:
SELECT t.sheetID,
counts.TotalsheetCount
FROM SomeTable t,
(SELECT sheetID, count(sheetID) as TotalsheetCount FROM SomeTable GROUP BY sheetID) counts
WHERE t.sheetID = counts.sheetID
It looks like you need a group-by expression:
select sheetID,
count(*) as TotalsheetCount
from SomeTable
group by sheetID
Is that it?
DC