Count by unique values in other fields in Oracle SQL - sql

I have table like this:
Year Month Type
2013 4 31
2013 3 31
2014 5 40
2014 6 41
2015 5 31
2015 7 40
2013 4 31
2013 3 31
2014 5 40
2014 6 41
2015 5 31
2015 7 40
2013 4 31
2013 3 31
I would like to count number of appearance of each combination. So output should be something like this:
Year Month Type Count_of_appearance
2013 3 31 3
2013 4 31 3
etc..
I've been using something like:
SELECT Year,
Month,
Type,
(SELECT COUNT (*)
FROM myTable
WHERE (...im lost in defining a condition in order to make this work...)
AS Count_of_appearance
FROM employee;
I'm lost at defining functional WHERE clause.
Problem is I a have a lot of fields like this and a lot of unique values. Table is 8Gb big.

You are looking for GROUP BY:
SELECT Year, Month, Type, COUNT(*) AS Count_of_appearance
FROM employee
GROUP BY Year, Month, Type
ORDER BY Year, Month, Type;
To ensure that the results are in the right order, you should include an ORDER BY as well.

Related

Total of Various Columns as a Separate Column in Oracle

Could you help me out with an issue I have in Oracle?
Let's say I have a table that tells me about how many items were sold in each month, and looks like so:
Item
January
February
March
April
Computer
3
5
2
9
TV
10
12
16
14
Camera
22
25
20
27
What I need in the output is a table that would count the total number of items sold over the period, and would look like this:
Item
January
February
March
April
Total
Computer
3
5
2
9
19
TV
10
12
16
14
52
Camera
22
25
20
27
94
I am honestly not sure how to do that. Should I use grouping()?
Thank you in advance.
You don't need to use grouping at all just try to plus all columns as a new column Total.
SELECT T.*,
(January + February + March + April) Total
FROM T

MS Access SQL – How can I count the occurrence of a number from one table in strings of another table

In MS Access 365 I have 2 tables and I want to count the occurrence of a year from the first table in part of a string of the second table, purely with SQL (so far I used VBA, but I want to simplify).
The first table (tDistinctYears) contains all the years, in which one of our members paid:
ID
PaymentYear
1
2015
2
2016
3
2017
3
2018
4
2019
5
2020
6
2021
7
2022
The second table (tPayments) has all payments from members with one column containing a membership number and the other one containing payment years. Sometimes a member pays for one year, sometime for several years. The table therefore looks like that:
MembershipNr
YearPayment
11
2016
11
2017
11
2018
26
2017
26
2018;2019
26
2020;2021;2022
38
2016
38
2017
38
2018;2019;2020;2021
I want a query which tells me how many members paid in which year:
PaymentYear
Count
2015
0
2016
2
2017
3
2018
3
2019
2
2020
2
2021
2
I used the following SQL query, which I found using various answers on stackoverflow:
SELECT tDistinctYears.PaymentYear, (COUNT(tPayments.YearPayment)) AS [Count]
FROM tDistinctYears
LEFT JOIN tPayments ON tDistinctYears.PaymentYear like "*" & tPayments.YearPayment & "*"
WHERE (tDistinctYears.PaymentYear > 0 AND tDistinctYears.PaymentYear <= YEAR(NOW()))
GROUP BY tDistinctYears.PaymentYear;
But what I get is this:
PaymentYear
Count
2015
0
2016
2
2017
3
2018
1
2019
0
2020
0
2021
0
It seems as if the above query does not use the “like” expression in the JOIN ON section.
Can someone help me, please?
I think you are close just alter column in where condition tPayments.YearPayment should be first and tDistinctYears.PaymentYear should be inside like operator.
SELECT tDistinctYears.PaymentYear, (COUNT(tPayments.YearPayment)) AS [Count]
FROM tDistinctYears
LEFT JOIN tPayments ON tPayments.YearPayment like "*" &
tDistinctYears.PaymentYear
& "*" WHERE (tDistinctYears.PaymentYear > 0 AND tDistinctYears.PaymentYear <=
YEAR(NOW()))
GROUP BY tDistinctYears.PaymentYear;

Determine the first occurrence of a particular customer visiting the store in a particular month

I need to determine the counts breakdown to per month (and year) of customers [alias'ed as Patient_ID] which made their first visit to a store. The date times of store visits are stored in the [MDT Review Date] column of the table.
Customers can come to the store multiple times throughout the year and increase the total count-> but what I require is ONLY the first time a customer visited.
E.g. Tom Bombadil visited the store once in January 2019, so count increased to 1, then again 4 times in March, so count should be 1 for the month of March and 0 for febraury and 1 for January, then again 4 times in October, then again 2 times in December.
I require that Tom Bombadil should be counted one and only once for a particular month, his first occurrence which was per month
The output should be like :
rn1 YEAR Month_Number Month Total_Count
1 2010 6 June 2
1 2010 7 July 1
1 2010 8 August 5
1 2010 10 October 5
1 2010 11 November 3
1 2011 1 January 4
1 2011 2 February 6
1 2011 4 April 7
1 2011 5 May 4
1 2011 6 June 10
1 2011 7 July 10
1 2011 8 August 14
1 2011 9 September 4
1 2011 10 October 8
1 2011 11 November 11
1 2011 12 December 11
1 2012 1 January 8
1 2012 2 February 21​
Please refer to my query. What I have attempts to use the windowing function COUNT to count the store visits per month. Then the ROW_NUMBER function attempts to assign a unique number to each visit. What am I doing wrong?
select
*
from
(select distinct
row_number() over (partition by p.Patient_ID, p.PAT_Forename1, p.PAT_Surname
order by PAT_Forename1, p.Patient_ID, PAT_Surname) AS rn1,
datepart(year, [DATE_COLUMN]) as YEAR,
datepart(month, [DATE_COLUMN]) as Month_Number,
datename(month,[DATE_COLUMN]) as Month,
count(p.Patient_ID) over (partition by datepart(year,[DATE_COLUMN]),
datename(month, [DATE_COLUMN])) as Total_Count
from
Tablename m
inner join
TableName p on m.PK_ID = p.PK_ID
) as temp
where
rn1 = 1​

SQL count ocurrences within time periods

I recently started up working with Access database in a project at my work (hospital) and got lots of useful tips from this site. However, I have now a problem that I can't figure out how to solve.
I have a table containing treatment dates (as well as other data) for lots of patients. My task is to count the number of treatments given within each week (and possibly month/quarter/year as well). The treatment dates are located in the column 'TreatDate' in the table 'Data'.
I have used DatePart to separate out year and week number as:
SELECT
DatePart('yyyy',[TreatStart]) AS Year, DatePart('ww',[TreatStart]) AS Week
FROM Data
ORDER BY DatePart('yyyy',[TreatStart]),DatePart('ww',[TreatStart]);
Which gives me:
Year Week
2006 16
2006 16
2006 16
2006 17
2006 17
2006 18
2006 19
2006 19
2006 19
... ...
How do I count the number of occurances in each week in order to get something like:
Year Week N
2006 16 3
2006 17 2
2006 18 1
2006 19 3
... ... ...
Best regards,
Mattias
Just add the group by on the same values by which you want count and add the count aggregate function to get the total count of the appointments at that given group.
SELECT DatePart('yyyy',[TreatStart]) AS Year, DatePart('ww',[TreatStart]) AS Week , COUNT(*) As N
FROM Data
GROUP BY DatePart('yyyy',[TreatStart]),DatePart('ww',[TreatStart])
ORDER BY DatePart('yyyy',[TreatStart]),DatePart('ww',[TreatStart]);
Use GROUP BY and COUNT:
SELECT DatePart('yyyy',[TreatStart]) AS Year,
DatePart('ww',[TreatStart]) AS Week,
COUNT(*) as N
FROM Data
GROUP BY DatePart('yyyy',[TreatStart]),DatePart('ww',[TreatStart])
ORDER BY DatePart('yyyy',[TreatStart]),DatePart('ww',[TreatStart]);
The output will be:
Year Week N
2006 16 3
2006 17 2
2006 18 1
2006 19 3

Using the lag function to find a moving average in SQL

I need to find a moving average for the previous 12 rows. I need to have my result set look like this.
t Year Month Sales MovingAverage
1 2010 3 20 NULL
2 2010 4 22 NULL
3 2010 5 24 NULL
4 2010 6 25 NULL
5 2010 7 23 NULL
6 2010 8 26 NULL
7 2010 9 28 NULL
8 2010 10 26 NULL
9 2010 11 29 NULL
10 2010 12 27 NULL
11 2011 1 28 NULL
12 2011 2 30 NULL
13 2011 3 27 25.67
14 2011 4 29 26.25
15 2011 5 26 26.83
For row 13 I need to average rows 1 to 12 and have the result returned in row 13 column MovingAverage. Rows 1-12 have a MovingAverage of NULL because there should be at least 12 previous rows for the calculation. Rows t, Year, Month, and Sales already exist. I need to create the MovingAverage row. I am using postgreSQL but the syntax should be very similar.
Don't use the lag() function. There is a build in moving average function. Well, almost:
select t.*, avg(sales) over (order by t range between 12 preceding and current row
from table t;
The problem is that this will produce an average for the first 11 months. To prevent that:
select t.*,
(case when row_number() over (order by t) >= 12
then avg(sales) over (order by t range between 12 preceding and current row
end) as MovingAvg
from table t;
Note that the syntax rows between instead of range between would be very similar for this query.