group by year month in postgresql - sql

customer Date location
1 25Jan2018 texas
2 15Jan2018 texas
3 12Feb2018 Boston
4 19Mar2017 Boston.
I am trying to find out count of customers group by yearmon of Date column.Date column is of text data type
eg: In jan2018 ,the count is 2

I would do something like the following:
SELECT
date_part('year', formattedDate) as Year
,date_part('month', formattedDate) as Month
,count(*) as CustomerCountByYearMonth
FROM
(SELECT to_date(Date,'DDMonYYYY') as formattedDate from <table>) as tbl1
GROUP BY
date_part('year', formattedDate)
,date_part('month', formattedDate)
Any additional formatting for dates could be done on the inner query that will allow for adjustments in case some single digit days need to be padded or a month has four letters instead of three etc.
By converting to date type, you can properly order by date type and not alphabetical etc.
Optionally:
SELECT
Year
,Month
,count(*) as CustomerCountByYearMonth
FROM
(SELECT
date_part('year', to_date(Date,'DDMonYYYY')) as Year
,date_part('month', to_date(Date,'DDMonYYYY')) as Month
FROM <table>) as tbl1
GROUP BY
Year
,Month

You shouldn't store dates in a text column...
select substring(Date, length(Date)-6), count(*)
from tablename
group by substring(Date, length(Date)-6)

I thought #Jarlh asked a good question -- what about dates like January 1? Is it 01Jan2019 or 1Jan2019? If it can be either, perhaps a regex would work.
select
substring (date from '\d+(\D{3}\d{4})') as month,
count (distinct customer)
from t
group by month
The 'distinct customer' also presupposes you may have the same customer listed in the same month, but you only want to count it once. If that's not the case, just remove 'distinct.'
And, if you wanted the output in date format:
select
to_date (substring (date from '\d+(\D{3}\d{4})'), 'monyyyy') as month,
count (distinct customer)
from t
group by month

If it is a date column, you can truncate the date:
select date_trunc('month', date) as yyyymm, count(*)
from t
group by yyyymm
order by yyyymm;
I really read that the type was date. For a string, just use string functions:
select substr(date, 3, 7) as mmmyyyy, count(*)
from t
group by mmmyyyy;
Unfortunately, ordering doesn't work in this case. You should really be storing dates using the proper type.

Related

Remove Duplicates and show Total sales by year and month

i am trying to work with this query to produce a list of all 11 years and 12 months within the years with the sales data for each month. Any suggestions? this is my query so far.
SELECT
distinct(extract(year from date)) as year
, sum(sale_dollars) as year_sales
from `project-1-349215.Dataset.sales`
group by date
it just creates a long list of over 2000 results when i am expecting 132 max one for each month in the years.
You should change your group by statement if you have more results than you expected.
You can try:
group by YEAR(date), MONTH(date)
or
group by EXTRACT(YEAR_MONTH FROM date)
A Grouping function is for takes a subsection of the date in your case year and moth and collect all rows that fit, and sum it up,
So a sĀ“GROUp BY date makes no sense, what so ever as you don't want the sum of every day
So make this
SELECT
extract(year from date) as year
,extract(MONTH from date) as month
, sum(sale_dollars) as year_sales
from `project-1-349215.Dataset.sales`
group by 1,2
Or you can combine both year and month
SELECT
extract(YEAR_MONTH from date) as year
, sum(sale_dollars) as year_sales
from `project-1-349215.Dataset.sales`
group by 1

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 query for multiple values of a column

I have db with names etc with date of birth. How can I get count of columns for all 12 months of the dates?
Exact code depends on the database you use; you should, somehow, "extract" month from date of birth in order to GROUP BY it.
In Oracle, you might have done it as
select to_char(date_of_birth), 'mon') dob_month,
count(*)
from your_table
group by to_char(date_of_birth, 'mon');
or
select extract(month from date_of_birth) dob_month,
count(*)
from your_table
group by extract(month from date_of_birth);

How do I correctly use the SQL Sum function with multiple variables and grouping?

I am trying to write an SQL statement based on the following code.
CREATE TABLE mytable (
year INTEGER,
month INTEGER,
day INTEGER,
hoursWorked INTEGER )
Assuming that each employee works multiple days over each month in a 3 year period.
I need to write an sql statement that returns the total hours worked in each month, grouped by earliest year/month first.
I tried doing this, but I don't think it is correct:
SELECT Sum(hoursWorked) FROM mytable
ORDER BY(year,month)
GROUP BY(month);
I am a little confused about how to operate the sum function in conjunction with thee GROUP BY or ORDER BY function. How does one go about doing this?
Try this:
SELECT year, month, SUM(hoursWorked)
FROM mytable
GROUP BY year, month
ORDER BY year, month
This way you will have for example:
2014 December 30
2015 January 12
2015 February 40
Fields you want to group by always have be present in SELECT part of query. And vice-versa - what you put in SELECT part, need be also in GROUP BY.
SELECT year, month, Sum(hoursWorked)as workedhours
FROM mytable
GROUP BY year,month
ORDER BY year,month;
You have to group by year and month.
Is this what you are trying to do. This will sum by Year/Month and Order by Year/Month.
Select [Year], [Month], Sum(HoursWorked) as WorkedHours
From mytable
Group By [Year], [Month]
Order by [Year], [Month]
You have to group by year and month, otherwise you will have the hours you worked on March 2014 and 2015 in one record :)
SELECT Sum(hoursWorked) as hoursWorked, year, month
FROM mytable
GROUP BY(year, month)
ORDER BY(year,month)
;

Sorting months while im converting them to text

I have to do a consult which must give me the following information:
Month | Quantity
-------------------
January | XX
February | XX
... | ..
So, I thought in:
select to_char(to_timestamp(to_char(date_part('month', orderdate), '999'), 'MM'), 'Mon'), count(*) as quantity from orders group by 1 ORDER BY 1
The problem is: months were sorted by "text" I mean:
Apr
Aug
Dec
...
How to solve it?
I suggest date_trunc() instead. It truncates date / timestamp to the given unit.
For two reasons:
You want the number of orders in August of a particular year, like 2012, not the sum for August of all years in the table. date_trunc('month', orderdate) does exactly that and prevents that you mix multiple years by accident. You get multiple rows for multiple years.
You can both ORDER BY and GROUP BY this one expression, the query is a bit faster.
SELECT to_char(date_trunc('month', orderdate), 'Mon') AS "Month" -- repeat expr.
,count(*) AS "Quantity"
FROM orders
GROUP BY date_trunc('month', orderdate) -- 1 item covers it
ORDER BY date_trunc('month', orderdate);
db<>fiddle here
Old sqlfiddle
For full month names, like your first example implies:
to_char(date_col, 'Month')
For non-English, localized names:
to_char(date_col, 'TMMonth')
Details in the manual.
First of all, your to_char is a lot more complicated that it needs to be, just this:
to_char(orderdate, 'Mon')
should be sufficient.
You're grouping and ordering by the first value that you select, that's what your 1 means. So of course the results are being sorted by month name, that's what you're asking for. Instead you want to group and order by the month component of the date, not its string representation. Something like this:
select to_char(orderdate, 'Mon') as "Month",
count(*) as "Quantity"
from orders
group by extract(month from orderdate), to_char(orderdate, 'Mon')
order by extract(month from orderdate)
You need both values in the GROUP BY to make it play nice with both your SELECT and your ORDER BY at the same time.