Sorting months while im converting them to text - sql

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.

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

Write a query to display the total month wise sales amount received in the past 1 year

Table StructureWrite a query to display the total month wise sales amount received in the past 1 year . Display details like sales month, total sales amount. Give an alias_name as MONTH for retrieved sales month, TURN_OVER for sales amount. Sort the result by amount in descending order.
(Hint: Use table Sales_info. Use to_char for retrieving the month. Net amount for sales amount calculation. Use sysdate for calculation of past 1 year sales. DATA IS CASE-SENSITIVE.)
The code I have written is fetching me all years sales data.
select to_char(Sales_Date,'Month')"MONTH"
Net_Amount as Turn_Over
from Sales_Info
where Sales_Date= add_months(Sysdate,-12)
select to_char(Sales_Date,'MON')"MONTH",
Net_Amount as TURN_OVER
from Sales_Info
where Sales_Date > add_months(Sysdate,-12)
order by Net_Amount desc;
I'm not going to do your homework for you, but here is a list of things currently missing from your query:
a comma in the SELECT list
you need greater than, not equals because you want all dates "more than the moment it was a year ago"
you need to break your data into groups where each group has the same month, and you need to sum up all the data in that month, so your query needs to have the words GROUP BY and SUM in it..
The code I have written is fetching me all years sales data
No, the query as it stands will be giving you only the sales that happened at exactly the current date-time, one year ago, which is probably 0 records
You are pretty close. What you are missing is the GROUP BY and summary functions:
select to_char(Sales_Date, 'Month') as "MONTH"
SUM(Net_Amount) as Turn_Over
from Sales_Info
where Sales_Date= add_months(Sysdate, -12)
group by to_char(Sales_Date, 'Month');
Note that there are still some significant issues with the query. For instance, I really am not a fan of using month names for what you are doing. It leaves out the year. In fact, the above query is going to combine data from the current month and the same month last year.
I would instead go for complete months. And use trunc() instead:
select trunc(Sales_Date, 'MON') as "MONTH"
SUM(Net_Amount) as Turn_Over
from Sales_Info
where Sales_Date = add_months(trunc(Sysdate, 'MON'), -12) and
Sales_Date < trunc(sysdate, 'MON')
group by to_char(Sales_Date, 'Month')
order by "MONTH".
In a real-world environment, this would typically provided cleaner, more useful results. In addition, because the first column is actually the date, it is easy to sort by.
The ans will be :
Select to_char(Sales_Date , 'MON' ) as "MONTH" , sum(Net_Amount) as TURN_OVER
from Sales_Info
where Sales_Date > add_months(Sysdate , -12)
group by to_char(Sales_Date , 'MON')
order by TURN_OVER desc;

group by year month in postgresql

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.

Oracle group orders by date and sum the total

My Orders table looks like:
order_id (number)
order_total (number)
created_date (timestamp)
status (varchar2)
My goal is to get a set of rows where each row represents all orders on that date, so I'm trying to group the orders by date and get the sum of the order_total. I'm also limiting the results by only selecting orders from the last 30 days.
To clarify, for example if there were 30 orders in the last 30 days all on unique days then I would get 30 rows in the result. Another example: if there were 10 orders on 30th July, and only 1 order on 31st July then I'm aiming to get 2 rows in the result set, with order_total summed for all 10 orders in the first row, and the second row would of course have the order_total of the single order on the 31st.
My attempt so far:
select
sum(order_total) total_amount,
to_char(created_date, 'DD/MM/YYYY') grouped_date
from
orders
where
status = 'Complete' and
created_date >= (sysdate-30)
group by
to_char(created_date, 'DD'), to_char(created_date, 'MM'), to_char(created_date, 'YYYY')
order by
created_date asc
This gives an error:
ORA-00936: missing expression
I have tried to use the solution from this question but I don't think it quite fits for my scenario (this is where my group by expression has come from).
Assuming order_id should not be there, and that created_date has a time component (which seems likely as it's a timestamp), you need to truncate the date to remove the time when doing the aggregation:
select
sum(order_total) as total_amount,
to_char(trunc(created_date), 'DD/MM/YYYY') as grouped_date
from
orders
where
status = 'Complete' and
created_date >= trunc(sysdate-30)
group by
trunc(created_date)
order by
trunc(created_date) asc
I've also applied trunc to the where clause, otherwise it would ignore any orders 30 days ago between midnight and whatever time you ran the query today. And I've used the trunc'd date directly in the order by, rather than the column alias, so that the order is right when you go across a month-end - ordering by the DD/MM/YYYY string value would put 01/07/2013 before 30/06/2013, for example.
Quick SQL Fiddle.

How to group quantities in a period of time

Im trying to group quantities regarding a time or period, i have the next table
SALES
SALES_DATE
SALES_ITEM
SALES_QUANTITY
The query that im doing it's
SELECT DATE,ITEM,SUM(QUANTITY)
FROM SALES
WHERE DATE BETWEEN "DATE1" AND "DATE2";
The problem is that i dont need the DATE to appear, if i look for the sales of october it should appear the sum of october without showing the date... Thank you very much for your help
Example:
What i get...
DATE ITEM SALES
2012-06-12 14152 7
2012-06-14 14152 15
2012-06-16 14157 25
What i need: query between 06-12 and 06-16
ITEM SALES
14152 22
14157 25
Thanks you very much
If you want the sum by month, you can include that in the group by expression. Here is one way:
SELECT extract(year from DATE) as yr, extract(month from date) as mon, ITEM, SUM(QUANTITY)
FROM SALES
WHERE DATE BETWEEN "DATE1" AND "DATE2"
group by extract(year from DATE), extract(month from date)
order by 1, 2
Although extract is standard SQL, not all databases support it. For instance, you might use to_char(date, 'YYYY-MM') in Oracle or datepart(month, date) in SQL Server.