I am trying to figure out how to have the results as if January is the first month in the results. Not to have it ordered alphabeticaly.
this is my query, but it has an error in the order by part:
SELECT datename(Month,(Orderdate)) AS Maand,
sum(SubTotal) AS omzet , sum(Freight) AS vervoerkosten
FROM Sales.SalesOrderHeader
WHERE Year(OrderDate) = 2012
GROUP BY datename(Month,(OrderDate))
ORDER BY Month(OrderDate) ASC
Instead, use MIN():
order by min(OrderDate) asc
This chooses the earliest date to define the rows.
It's not that everything you group by needs to selected.
So you can also add the MONTH(OrderDate) to the GROUP BY.
...
GROUP BY YEAR(OrderDate), MONTH(OrderDate), DATENAME(Month,OrderDate)
ORDER BY YEAR(OrderDate), MONTH(OrderDate)
Related
I need some help in using the sum and max functions in SQL.
I want to display for each year, the month with the highest sales.
I have 2 tables
sales.orderline:
orderno - prodno - quantity - price - linetotal
sales.custorder:
orderno - custno - salesrep - orderdate
This is what I have:
select year(orderdate) as year, month(orderdate) as month, sum(linetotal) as sales
from sales.custorder
inner join sales.orderline on sales.custorder.orderno = sales.orderline.orderno
where year(orderdate) is not null and month(orderdate) is not null
group by month(orderdate), year(orderdate)
My problem is that this shows the total for each month of the year and I don't know how to select only the month with the highest total for each year. My only idea was max(sum()) which doesn't work.
You can use window functions, if your database supports them:
select *
from (
select
year(orderdate) as yr,
month(orderdate) as mn,
sum(linetotal) as sales,
rank() over(partition by year(orderdate) order by sum(linetotal) desc) rn
from sales.custorder
inner join sales.orderline on sales.custorder.orderno = sales.orderline.orderno
where year(orderdate) is not null and month(orderdate) is not null
group by month(orderdate), year(orderdate)
) t
where rn = 1
order by yr
Note that rank() allows top ties, if any.
Unrelated: condition year(orderdate) is not null and month(orderdate) is not null can probably be simplified as orderdate is not null.
You can use row_number(). Let's say that if you have two months with same sales in a year then you can use dense_rank().
select
year,
month,
sales
from
(
select
year(orderdate) as year,
month(orderdate) as month,
sum(linetotal) as sales,
row_numbe() over (partition by year(orderdate) order by sum(linetotal) desc) as rnk
from sales.custorder sc
inner join sales.orderline so
on sc.orderno = so.orderno
where year(orderdate) is not null
and month(orderdate) is not null
group by
month(orderdate),
year(orderdate)
) val
where rnk = 1
order by
year,
month
So I'm trying to find the month/year that had the highest number of sale transactions.
my query currently is:
SELECT
DATENAME(M, OrderDate) as orderMonth,
year(OrderDate) as orderYear,
count(SalesOrderID) as orderCount
FROM
Sales.SalesOrderHeader soh
GROUP BY OrderDate
HAVING SUM(soh.SalesOrderID) >= ALL (
SELECT SUM(SalesOrderID) FROM Sales.SalesOrderHeader
GROUP BY OrderDate
)
however if I run everything above the HAVING line so that it returns all columns instead of just the highest column, it returns several duplicates of months/years and the orderCounts. for example, June 2011 has about 30 rows being returned in this query, each of those ranging somewhere between 2 and 11 orderCounts, in total the query returns 1124 rows, where it should only be returning 38 since the sales range from 2011 - 2014 and there's 38 months total within that range.
I'm pretty sure I need to specify a monthly group and should be changing my GROUP BYs to something like:
GROUP BY DATENAME(month, soh.OrderDate), DATENAME(YYYY, soh.OrderDate)
but then i get an error "Each GROUP BY expression must contain at least one column that is not an outer reference"
Your problem is that you are aggregating by OrderDate rather than by the month and year. So, your version of the query should look like:
SELECT DATENAME(MONTH, OrderDate) as orderMonth,
YEAR(OrderDate) as orderYear,
COUNT(*) as orderCount
FROM Sales.SalesOrderHeader soh
GROUP BY DATENAME(MONTH, OrderDate), YEAR(OrderDate)
HAVING COUNT(*) >= ALL (SELECT COUNT(*)
FROM Sales.SalesOrderHeader soh2
GROUP BY DATENAME(MONTH, OrderDate), YEAR(OrderDate)
);
However, no one would really write the query like that. It is simpler and more performant to use TOP and ORDER BY. The equivalent of your query is:
SELECT TOP (1) WITH TIES DATENAME(MONTH, OrderDate) as orderMonth,
YEAR(OrderDate) as orderYear,
COUNT(*) as orderCount
FROM Sales.SalesOrderHeader soh
GROUP BY DATENAME(MONTH, OrderDate), YEAR(OrderDate)
ORDER BY orderCount DESC;
Both these return all months with the maximum value -- if there are duplicates. If you want to guarantee only one row in the result set, use SELECT TOP (1) rather than SELECT TOP (1) WITH TIES.
Not sure which sql syntax you are using, but you could just sort by transactions and select the highest record?
SELECT top 1
DATENAME(M, OrderDate) as orderMonth,
year(OrderDate) as orderYear,
count(SalesOrderID) as orderCount
FROM
Sales.SalesOrderHeader soh
Group by orderMonth, orderYear
order by orderCount asc
I'm trying to find the month with the most sales, I've been able display every month with its sales using:
SELECT Month(orderdate) AS Month,
Year(orderdate) AS Year,
Sum(salesorderid) AS Sales
FROM sales.salesorderheader
GROUP BY Month(orderdate),
Year(orderdate)
Which shows
But I just want to select the top sales month.
If I'm correct, you want to print single result with the max sales
And here "salesorderid" is the total sales of that month
Try adding MAX
SELECT Month(orderdate) AS Month,
Year(orderdate) AS Year,
MAX(Sum(salesorderid)) AS Sales
FROM sales.salesorderheader
GROUP BY Month(orderdate),
Year(orderdate)
Or try using HAVING clause
SELECT Month(orderdate) AS Month,
Year(orderdate) AS Year,
Sum(salesorderid) AS Sales
FROM sales.salesorderheader
GROUP BY Month(orderdate),
Year(orderdate)
HAVING MAX(Sum(salesorderid))
since Sum(salesorderid) is the total sales this might work...
You have to group it first by year then month. Then use count() not sum() (seems your column is SalesOrderID), but if you are trying to get the sum of sales it should be something like sum(salesamount).
Also change your column aliases, those are sql keywords.
select month(OrderDate) as oMonth, year(OrderDate) as oYear
, count(1) as SalesCount
from SalesOrderHeader
group by year(OrderDate), month(OrderDate)
getting the most number of sales.
select top 1 * from (
select month(OrderDate) as oMonth, year(OrderDate) as oYear
, count(1) as SalesCount
from SalesOrderHeader
group by year(OrderDate), month(OrderDate)) t1
order by t1.SalesCount desc
Just use top (1):
SELECT TOP (1) Month(orderdate) AS Month,
Year(orderdate) AS Year,
Sum(salesorderid) AS Sales
FROM sales.salesorderheader
GROUP BY Month(orderdate), Year(orderdate)
ORDER BY Sales DESC;
You can try
Using ORDER BY "field name" DESC
If field "salesorderid" not in type number, ORDER BY function can't run. So you can change before, use CAST("field name" AS Decimal)
Check Below code snippet
SELECT Month(a.orderdate) AS Month,
Year(a.orderdate) AS Year,
Sum(a.salesorderid) AS Sales
FROM sales.salesorderheader a
GROUP BY Month(a.orderdate),Year(a.orderdate)
ORDER BY CAST(a.Sum(a.salesorderid), AS Decimal) DESC
I'm trying to write a query in SQL that calculated the total in orders (dollar amount) per month for the current year.
My table is setup this way:
OrderID OrderTotal OrderDate
5598745 85.70 2016-07-29
5598744 184.75 2016-07-25
5598743 847.50 2016-06-20
5598742 50.00 2016-06-05
So my query should display something like this:
June $897.50
July $270.45
etc...
I'm working with this without success:
SELECT
month(OrderDate) AS month_name,
SUM(OrderTotal) AS sum_of_month,
AVG(SUM(OrderTotal)) OVER () AS avg_sum
FROM
[db].[dbo].[orders]
WHERE
YEAR(OrderDate) = YEAR(GetDate())
for month sum you should use group by
SELECT month(OrderDate) AS month_name,
SUM(OrderTotal) AS sum_of_month
AVG(OrderTotal) AS AVG_of_month
FROM [db].[dbo].[orders]
WHERE YEAR(OrderDate) = YEAR(GetDate())
GROUP BY month(OrderDate);
Use DateName() to get the Month's name
Declare #Table table (OrderTotal money,OrderDate Date)
Insert into #Table values
(85.70,'2016-07-29'),
(184.75,'2016-07-25'),
(847.50,'2016-06-20'),
(50.00,'2016-06-05')
Select MonthName=DateName(MM,OrderDate)
,Total=sum(OrderTotal)
From #Table
Where Year(OrderDate) = Year(GetDate())
Group By Month(OrderDate),DateName(MM,OrderDate)
Order By Month(OrderDate)
Returns
MonthName Total
June 897.50
July 270.45
Try this it may work
SELECT
month(OrderDate) AS month_name,
SUM(OrderTotal) AS sum_of_month,
AVG(SUM(OrderTotal)) OVER () AS avg_sum
FROM
[db].[dbo].[orders]
WHERE
YEAR(OrderDate) = YEAR(GetDate())
order by month(OrderDate)
Here's a simple query for computing sum for every month.
select datename(month, dateadd(month, month(OrderDate), 0) - 1) as month_name,
sum(OrderTotal) as sum_of_month
from Orders
where year(OrderDate) = year(getdate())
group by month(OrderDate)
order by month(OrderDate)
It seems that you want to obtain an average of all the sums. I don't think that it is a good idea to present it in this table. The same number would be presented for each row. Instead I recommend a separate query:
select avg(t.month_sum) from
(select sum(OrderTotal) as month_sum from Orders
where year(OrderDate) = year(getdate())
group by month(OrderDate)
) as t
SELECT YEAR(OrderDate) 'Year', SUM(TotalDue)
FROM Sales
GROUP BY OrderDate
Order BY OrderDate
How do I add each year together as ONE row?
I wrote the query above, but the result still has the TotalDue by Year as individual rows.
For example
You have a problem in the GROUP BY statement because it operates on a selected column:
SELECT YEAR(OrderDate) theYear, SUM(Due) TotalDue
FROM Sales
GROUP BY theYear --Here you can either order by TotalDue or by theYear,
-- otherwise you will get the errors you mentioned
You should GROUP BY Year, not OrderDate:
SELECT YEAR(OrderDate), SUM(TotalDue)
FROM Sales
GROUP BY YEAR(OrderDate)
Order BY OrderDate
You should group by the year of the order date and no the OrderDate itself.
SELECT YEAR(OrderDate) AS `Year`, SUM(TotalDue)
FROM Sales
GROUP BY YEAR(OrderDate)
Order BY Year
SELECT YEAR(OrderDate) 'Year', SUM(TotalDue)
FROM Sales
GROUP BY YEAR(OrderDate)
You need to re-group results
SELECT y, Sum(s) from
(
SELECT YEAR(OrderDate) as y , SUM(TotalDue) as s
FROM Sales
GROUP BY OrderDate
)
group by y
Order BY y