PostgreSQL - max(count()) agregation with group by - sql

I have a table that contains unique transactions along with the year of the transaction and the employee who executed it. I need to find the employee with most transactions in each year.
I need a table with each year, the employee w/ most transactions in that year, and the number of transactions they had in that year.
This is as close as I am able to get without producing an error. I am unable to select the employee without producing an aggregation error.
select year, max(num_trans)
from (select year, employee, count(trans_id) as num_trans
from transactions
group by year, employee) as x
group by year
I am curious about how to work around this.

Use distinct on:
select distinct on (year) year, employee, count(*) as num_trans
from transactions
group by year, employee
order by year, count(*) desc;
distinct on is a handy Postgres extension to standard SQL that keeps the first row in a group of rows. The groups are defined by the distinct on key(s). Which row is first is determined by the order by.

Related

How to aggregate in SQL by having clause

The below is the query I'm using, I would like to add two more columns in the select statement which I have and noted them in the group by clause but the total results are different. The below script gives me the correct total count but I want to see the totals also for a column called transaction, and a column called employee. The total count should still be the same.
SELECT SUB.YEAR, SUM(SUB.TOTAL_COUNT), SUM(SUB.TOTAL_SPENT)
FROM (
SELECT YEAR, COUNT(*) AS TOTAL_COUNT, SUM($SPENTX) AS TOTAL_SPENT, CUSTOMERID
FROM TABLE A
WHERE YEAR = 2017
GROUP BY YEAR, CUSTOMERID
HAVING SUM($SPENTX)<=1000
) SUB
GROUP BY SUB.YEAR

Count distinct while grouping in MS Access 2010

I have a database of sales and I want to be able to see what has sold during a particular time frame over the years i.e. see what sold most in the last 10 years between July 1 and July 15. Problem is that not all the items were sold every year, and I need to be able to get the average sold. I was able to count distinct years in MySQL but after migrating to Access I can't figure out how to count distinct while still grouping by the individual product.
Relevant fields are StockID (the items' unique id) and TransDate (a datetime that I pull the year from) I've tried things similar to SELECT Count(*) FROM (SELECT DISTINCT YEAR(Transdate) from Sales) inside my other query but that always gives me the count from all items (basically giving the number of years in the database) rather than a count for each item.
TL;DR I can either count distinct on the whole DB which is useless or group by StockID without counting distinct which is mildly less useless.
Seems you are looking for select with group by ..
select StockID, count(*)
from (select distinct stockID, Year( Transdate) from my_table )
group StockID

SQLPLUS (Oracle) - Get MAX COUNT of GROUPBY

I need to identify which Month has the most entries. Ive used the TO_DATE function to format the date column to just the MONTH. Also, SELECT COUNT(*) in combination with the GROUP BY Clause I am able to return all records month and count attributes.
However, I need to be able to only return one row that is the MAX of the COUNT. IVE atempted to do so by adding a HAVING clause but returns an error. I suspect I need a subquery in here somewhere but am unsure as to how to go about it.
SELECT TO_CHAR(P.DATEREGISTERED,'MONTH') MONTH, COUNT(*) COUNT
FROM PET P
GROUP BY TO_CHAR(P.DATEREGISTERED,'MONTH')
HAVING COUNT = MAX(COUNT);
Another Attempt:
SELECT TO_CHAR(P.DATEREGISTERED,'MONTH') MONTH, COUNT(*) COUNT
FROM PET P
GROUP BY TO_CHAR(P.DATEREGISTERED,'MONTH')
HAVING COUNT(*) = (SELECT MAX(TO_CHAR(P.DATEREGISTERED,'MONTH')) FROM PET P);
In the query with alias, you are grouping by Month and getting a count of the number of records and you are checking whether that count is same as the maximum of the "date value" converted to month string. They are not even comparisons of the same type.
The query that you have provided in the answer correctly compares the count on both sides.
Another way to rewrite the query would be
select * from
(SELECT TO_CHAR(P.DATEREGISTERED,'MONTH') MONTH, COUNT(*) COUNT
FROM PET P
GROUP BY TO_CHAR(P.DATEREGISTERED,'MONTH') order by count(*) desc )
where rownum=1
Here we order the records in the subquery by descending order of the count and then getting the first row from that.
The bellow code works and returns the correct response. It is unclear to me as to why it works but the above attempts (w/ aliases) do not.
SELECT TO_CHAR(P.DATEREGISTERED,'MONTH') MONTH, COUNT(*) COUNT
FROM PET P
GROUP BY TO_CHAR(P.DATEREGISTERED,'MONTH')
HAVING COUNT(*) = (SELECT MAX(COUNT(*)) FROM PET P GROUP BY TO_CHAR(P.DATEREGISTERED,'MONTH'));

count duplicates and non duplicates

Using MS Access SQL
Is it possible to;
list and count all duplicates in one field based on another field?
list all non duplicates in one field based on another field?
Example database below
Based on your results, you just want a simple group by:
select name, year, count(*)
from [table]
group by name, year;
One statement cannot return two different headers. I mean, you could run two queries:
select name, year, count(*) as NumDuplicates
from [table]
group by name, year
having count(*) > 1;
select name, year, count(*) as NumNonDuplicates
from [table]
group by name, year
having count(*) = 1;

Select values with duplicate max values sql

I have a table made up of dates and sales totals for the particular date. I would like to be able to query the table and select the following: max sales, the date associated with the max sale figure, sum of all sales, and the minimum date in the table. One additional complication is that there are duplicate max values. I don't care which max value is chosen but I just want one at random. This is for Oracle.
Here is what I tried. It was using a sub query.
Select sales, date, min(date), sum(sales) from table
Where sales = (select distinct(max(sales)) from table)
select
max(sales),
max(date_) keep (dense_rank first order by sales desc),
sum(sales),
min(date_)
from
table_
See also This SQL Fiddle