Count distinct while grouping in MS Access 2010 - sql

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

Related

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

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.

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

SQL grouping with multiple rows

There's a table that I use that lists invoice detail. So for instance let's say a customer checks out with 2 items, there are 2 rows for each item.
Right now my SQL Query looks like this:
Select date
,order_id
,count(distinct(item_name))
from Table_1
group by 1,2
Rather than grouping it by order_id. Is there anyway to modify this query to find the number of Orders that have X amount of items on a specific date. So on 1/1/1990 5 orders have 3 items, 6 orders have 2 items, etc.
Thanks for the help!
If I'm understanding your question correctly, you could use a subquery grouping by the item count:
select t.date, t.itemCount, t.count(order_id)
from (
Select date
,order_id
,count(distinct(item_name)) AS itemCount
from Table_1
group by 1,2
) AS t
group by date, itemCount

How to count rows in SQL Server 2012?

I am trying to find whether a person (id = A3) is continuously active in a program at least five months or more in a given year (2013). Any suggestion would be appreciated. My data look like as follows:
You simply use group by and a conditional expression:
select id,
(case when count(ActiveMonthYear) >= 5 then 'YES!' else 'NAW' end)
from table t
where ListOfTheMonths between '201301' and '201312'
group by id;
EDIT:
I suppose "continuously" doesn't just mean any five months. For that, there are various ways. I like the difference of row numbers approach
select distinct id
from (select t.*,
(row_number() over (partition by id order by ListOfTheMonths) -
count(ActiveMonthYear) over (partition by id order by ListOfTheMonths)
) as grp
from table t
where ListOfTheMonths between '201301' and '201312'
) t
where ActiveMonthYear is not null
group by id, grp
having count(*) >= 5;
The difference in the subquery is constant for groups of consecutive active months. This is then used a grouping. The result is a list of all ids that meet this criteria. You can add a where for a particular id (do it in the subquery).
By the way, this is written using select distinct and group by. This is one of the rare cases where these two are appropriately used together. A single id could have two periods of five months in the same year. There is no reason to include that person twice in the result set.

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