Select only months which have data for a specified Year - sql

I would like a query which selects only those month's which have data for a specified year but I'm not quite sure how to achieve this. Here is what I have got so far:
select MONTH(DateRaised) as 'Month'
from Complaints
where
(select COUNT(*)
from Complaints
where YEAR(DateRaised) = 2000) > 0
group by MONTH(dateraised)
order by MONTH(dateraised)
So if my data had a Complaint from May, August and December in 2000, then I would only like 5, 8 and 12 to appear in my query, is this possible?

select DISTINCT MONTH(DateRaised) AS 'Month'
from Complaints
where YEAR(DateRaised) = 2000

select MONTH(DateRaised) as 'Month'
from Complaints
where YEAR(DateRaised) = 2000
ORDER BY MONTH(dateraised)

SELECT MONTH(DateRaised) as 'Month', COUNT(*) AS count
FROM Complaints
WHERE YEAR(DateRaised) = 2000
GROUP BY MONTH(dateraised)
ORDER BY MONTH(dateraised)

Related

Retrieve Customers with a Monthly Order Frequency greater than 4

I am trying to optimize the below query to help fetch all customers in the last three months who have a monthly order frequency +4 for the past three months.
Customer ID
Feb
Mar
Apr
0001
4
5
6
0002
3
2
4
0003
4
2
3
In the above table, the customer with Customer ID 0001 should only be picked, as he consistently has 4 or more orders in a month.
Below is a query I have written, which pulls all customers with an average purchase frequency of 4 in the last 90 days, but not considering there is a consistent purchase of 4 or more last three months.
Query:
SELECT distinct lines.customer_id Customer_ID, (COUNT(lines.order_id)/90) PurchaseFrequency
from fct_customer_order_lines lines
LEFT JOIN product_table product
ON lines.entity_id= product.entity_id
AND lines.vendor_id= product.vendor_id
WHERE LOWER(product.country_code)= "IN"
AND lines.date >= DATE_SUB(CURRENT_DATE() , INTERVAL 90 DAY )
AND lines.date < CURRENT_DATE()
GROUP BY Customer_ID
HAVING PurchaseFrequency >=4;
I tried to use window functions, however not sure if it needs to be used in this case.
I would sum the orders per month instead of computing the avg and then retrieve those who have that sum greater than 4 in the last three months.
Also I think you should select your interval using "month(CURRENT_DATE()) - 3" instead of using a window of 90 days. Of course if needed you should handle the case of when current_date is jan-feb-mar and in that case go back to oct-nov-dec of the previous year.
I'm not familiar with Google BigQuery so I can't write your query but I hope this helps.
So I've found the solution to this using WITH operator as below:
WITH filtered_orders AS (
select
distinct customer_id ID,
extract(MONTH from date) Order_Month,
count(order_id) CountofOrders
from customer_order_lines` lines
where EXTRACT(YEAR FROM date) = 2022 AND EXTRACT(MONTH FROM date) IN (2,3,4)
group by ID, Order_Month
having CountofOrders>=4)
select distinct ID
from filtered_orders
group by ID
having count(Order_Month) =3;
Hope this helps!
An option could be first count the orders by month and then filter users which have purchases on all months above your threshold:
WITH ORDERS_BY_MONTH AS (
SELECT
DATE_TRUNC(lines.date, MONTH) PurchaseMonth,
lines.customer_id Customer_ID,
COUNT(lines.order_id) PurchaseFrequency
FROM fct_customer_order_lines lines
LEFT JOIN product_table product
ON lines.entity_id= product.entity_id
AND lines.vendor_id= product.vendor_id
WHERE LOWER(product.country_code)= "IN"
AND lines.date >= DATE_SUB(CURRENT_DATE() , INTERVAL 90 DAY )
AND lines.date < CURRENT_DATE()
GROUP BY PurchaseMonth, Customer_ID
)
SELECT
Customer_ID,
AVG(PurchaseFrequency) AvgPurchaseFrequency
FROM ORDERS_BY_MONTH
GROUP BY Customer_ID
HAVING COUNT(1) = COUNTIF(PurchaseFrequency >= 4)

How to get number of billable customers per month SQL

This is what my table looks like:
NOTE: Don't worry about the BMI field being empty in some rows. We assume that each row is a reading. I have omitted some columns for privacy reasons.
I want to get a count of the number of active customers per month. A customer is active if they have at least 18 readings in total (1 reading per day for 18 days in a given month). How do I write this SQL query? Assume the table name is 'cust'. I'm using SQL Server. Any help is appreciated.
Presumably a patient is a customer in your world. If so, you can use two levels of aggregation:
select yyyy, mm, count(*)
from (select year(createdat) as yyyy, month(createdat) as mm,
patient_id,
count(distinct convert(date, createdat)) as num_days
from t
group by year(createdat), month(createdat), patient_id
) ymp
where num_days >= 18
group by yyyy, mm;
You need to group by patient and the month, then group again by just the month
SELECT
mth,
COUNT(*) NumPatients
FROM (
SELECT
EOMONTH(c.createdat) mth
FROM cust c
GROUP BY EOMONTH(c.createdat), c.patient_id
HAVING COUNT(*) >= 18
-- for distinct days you could change it to:
-- HAVING COUNT(DISTINCT CAST(c.createdat AS date)) >= 18
) c
GROUP BY mth;

SQL Sum and Count Separated by Month

I am writing a script that query's a table and counts all rows that have a status of 10 and separates the total count by month. Something is
not right considering I have two Decembers in my results.
In November, there is only one date in it meaning two rows have a status of 10 and are under the same date (11-04). December has 252 rows on the same date (12-04) and 1 row with a 12-05 date .
How to query and separate a count and date by months?
Any help is most appreciated.
SELECT CONVERT(CHAR(3), Datename(month, datecomplete)) AS Month,
Count(*) AS Val
FROM nwds
WHERE status = 10
GROUP BY Datediff(month, 0, datecomplete),
datecomplete
My Results
Nov 2
Dec 252
Dec 1
Desired Results
Nov 2
Dec 253
SELECT LEFT(DATENAME(M, datecomplete), 3) AS Month,
Count(*) AS Val
FROM nwds
WHERE status = 10
GROUP BY LEFT(DATENAME(M, datecomplete), 3)
If you have ever get data for different years, you can add the year to the GROUP BY.
SELECT LEFT(DATENAME(M, datecomplete), 3) AS Month,
YEAR(datecomplete) AS Year,
Count(*) AS Val
FROM nwds
WHERE status = 10
GROUP BY LEFT(DATENAME(M, datecomplete), 3), YEAR(datecomplete)
datecomplete should be excluded from group by, or the results would be grouped by day. Grouping needs to be on month and year part of datecomplete column.
SELECT
CONVERT(CHAR(3), Datename(month, datecomplete)) AS Month,
count(*) AS Val
FROM nwds
WHERE status = 10
GROUP BY CONVERT(CHAR(3), Datename(month, datecomplete)) ,
datepart(yyyy, datecomplete)
Try this
select CONVERT(char(3),DATENAME(MONTH,datecomplete)) as [month],
count(*) as val
from nwds
WHERE status = 10
group by CONVERT(char(3),DATENAME(MONTH,datecomplete))

More efficient way of getting count from every month of the year

I was wondering if there's a more efficient way of getting a count from every month of the year other then the way I'm currently doing. Currently I'm using a single select statement to get count from say Jan, Mar, so on and then joining them all into a single select statement.
Select distinct
count(item1 + item2) as 'Count of Items',
month(sub_date) as 'month'
from table1
where month(sub_date)='1'
and year(sub_date)='2012'
I would repeat that from month 1-12 and then join the 12 select statement to get a table of something like this
jan feb mar apr may jun july aug sept oct nov dec
1 2 2 1 3 5 5 2 6 7 2 1
Any information on how to go about redoing my query would be appreciated.
You should be able to use a GROUP BY on both the month(sub_date) and year(sub_date):
Select
count(item1 + item2) as 'Count of Items',
month(sub_date) as 'month',
year(sub_date) as year
from table1
group by month(sub_date), year(sub_date)
The result for this will be in multiple rows. the GROUP BY both the month and year will allow you to return multiple years, if you want to return only 2012, then you could include your original WHERE year(sub_date) =2012 clause similar to this:
Select
count(item1 + item2) as 'Count of Items',
month(sub_date) as 'month'
from table1
where year(sub_date) = 2012
group by month(sub_date)
Then if you want the data in a single row for each year, then you can apply the pivot function.
select *
from
(
Select item1 + item2 Items,
month(sub_date) as 'month'
from table1
where year(sub_date) =2012
) src
pivot
(
sum(Items)
for month in ([1], [2])
) piv
See SQL Fiddle with Demo. The PIVOT function transforms data from rows into columns.
GROUP BY is what you want: http://msdn.microsoft.com/en-us/library/ms177673.aspx
SELECT MONTH(sub_date) AS [month],
COUNT(item1 + item2) AS [Count of Items]
FROM table1
WHERE YEAR(sub_date) = 2012
GROUP BY MONTH(sub_date)
This assumes, as I've surmised from your post, that you just want 12 rows, one for each month of a given year (in this case, 2012). If you want to include all years, then you can add that to your GROUP BY clause like so:
GROUP BY YEAR(sub_date), MONTH(sub_date)

SQL Query to fetch number of employees joined over a calender year, broken down per month

I'm trying to find the number of employees joined over a calender year, broken down on a monthly basis. So if 15 employees had joined in January, 30 in February and so on, the output I'd like would be
Month | Employees
------|-----------
Jan | 15
Feb | 30
I've come up with a query to fetch it for a particular month
SELECT * FROM (
SELECT COUNT(EMP_NO), EMP_JN_DT
FROM EMP_REG WHERE
EMP_JN_DT between '01-NOV-09' AND '30-NOV-09'
GROUP BY EMP_JN_DT )
ORDER BY 2
How do I extend this for the full calender year?
SELECT Trunc(EMP_JN_DT,'MM') Emp_Jn_Mth,
Count(*)
FROM EMP_REG
WHERE EMP_JN_DT between date '2009-01-01' AND date '2009-12-31'
GROUP BY Trunc(EMP_JN_DT,'MM')
ORDER BY 1;
If you do not have anyone join in a particular month then you'd get no row returned. To over come this you'd have to outerjoin the above to a list of months in the required year.
SELECT to_date(EMP_JN_DT,'MON') "Month", EMP_NO "Employees"
FROM EMP_REG
WHERE EMP_JN_DT between date '2009-01-01' AND date '2009-12-31'
GROUP by "Month"
ORDER BY 1;
http://www.techonthenet.com/oracle/functions/extract.php
There is a function that returns month. What you need to do is just put it in group by
The number of employees in January can be selected in the following way:
SELECT EXTRACT(MONTH FROM HIREDATE) AS MONTH1, COUNT(*)
FROM employee
WHERE EXTRACT(MONTH FROM HIREDATE)=1
GROUP BY EXTRACT(MONTH FROM HIREDATE)