SQL: Outputting month names in correct order - sql

I am using the query composer on Google BigQuery.
I want to output the months in the correct order, e.g. starting with January, ending with December.
Here is my query:
SELECT month, gender, SUM(cost) AS Cost
FROM [medicare.medicareTable]
GROUP BY month, gender
ORDER BY month, gender
Without the ORDER BY above, the months were in a completely random order. Now they are alphabetised, which is a little better but still not what I want.
Using the above query, the output looks like this: https://docs.google.com/spreadsheets/d/18r_HhY1jG3Edkj5Nk8gDM_eSQ_1fI6ePHSZuJuoAppE/edit?usp=sharing
Thanks to anyone who can help.

for BigQuery Standard SQL you can use PARSE_DATE(). You can see Supported Format Elements for DATE
WITH m AS (
SELECT 'January 01 2016' AS d UNION ALL
SELECT 'February 01 2016' AS d UNION ALL
SELECT 'March 01 2016' AS d
)
SELECT d, EXTRACT(month FROM PARSE_DATE('%B %d %Y', d)) AS month_number
FROM m
ORDER BY month_number

You can try to get month number from month name and sort is ascending order.
Syntax for SQL Server
select DATEPART(MM,'january 01 2016') -- returns 1
So you can try something like this
SELECT month, gender, SUM(cost) AS Cost
FROM [medicare.medicareTable]
GROUP BY month, gender
ORDER BY datepart(MM,month + ' 01 2016'),gender
Hope this helps

Related

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;

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)
;

How can I display a result of data in order by a month-year combine column in sql?

I want to display a below data in order by first take month and then year
count Date
------- ----------
5 Aug 2011
6 jan 2008
10 feb 2009
I want to result as a first display a 2008 year, then 2009 like wise ordering wise date and also should display month in order wise
Assumptions:
You are trying to count records grouping by year and month
You have a table named Table1 with a column named EventDate
You are using SQL Server (you didn't specify)
You don't mind having extra columns in the output (you can ignore the columns you don't need)
You want to order by count, then year, then month
Based on these assumptions, the following should give you what you want.
SELECT COUNT(*) AS Count,
CONVERT(CHAR(3), DATENAME(MONTH, EventDate))
+ ' ' + CONVERT(CHAR(4), YEAR(EventDate)) AS Date,
MIN(YEAR(EventDate)) AS Year, MIN(MONTH(EventDate)) AS Month
FROM Table1
GROUP BY CONVERT(CHAR(4), YEAR(EventDate)),
CONVERT(CHAR(3), DATENAME(MONTH, EventDate))
ORDER BY COUNT(*), Year, Month
Here is the solution..
select convert(char(3), Date, 0)+' '+RIGHT(CONVERT(varchar, YEAR(Date)), 4) as [Date]
,count(id) as Count from Tabletest
group by convert(char(3), Date, 0)+' '+ RIGHT(CONVERT(varchar, YEAR(Date)), 4),month(Date),YEAR(Date)
order by YEAR(Date),MONTH(Date)

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.

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)