How to get specific SQL counts for each year? - sql

I am trying to get specific counts of bike sales per year, but now I'm only getting a total count of sales over the 5 year period and not broken up by specific years.
--CURRENT CODE:
Select datepart(year, C.TransactionDate) AS SalesYear,
SUM(COUNT(B.SerialNumber)) OVER() AS CountOfSerialNumber
FROM BIKE..Bicycle AS B
INNER JOIN BIKE..CustomerTransaction AS C on B.CustomerID = C.CustomerID
WHERE ModelType = 'Mountain' AND
TransactionDate BETWEEN '20000101' AND '20041231'
GROUP BY datepart(year, C.TransactionDate)
ORDER BY datepart(year, C.TransactionDate) ASC
--And my resulting output reads:
SalesYear | CountOfSerialNumber
2000 9431
2001 9431
2002 9431
2003 9431
2004 9431

You should be able to get the count without using SUM or OVER. OVER can be used to get a percentage of the total, if that's something you wanted to do.
SELECT DATEPART(YEAR, C.TransactionDate) AS SalesYear, COUNT(B.SerialNumber) AS Quantity,
COUNT(B.SerialNumber) * 100.0 / SUM(COUNT(B.SerialNumber)) OVER() AS Percentage
FROM BIKE..Bicycle AS B
INNER JOIN BIKE..CustomerTransaction AS C ON C.CustomerID = B.CustomerID
WHERE B.ModelType = 'Mountain' AND C.TransactionDate BETWEEN '20000101' AND '20041231'
GROUP BY DATEPART(YEAR, C.TransactionDate)
ORDER BY DATEPART(YEAR, C.TransactionDate) ASC

Related

T-SQL query to summarize sales for ALL YEARS: with total per month per year, and cumulative monthly amounts

I need to create a Sales Report that shows all years sales per month, and cumulative sales.
The database table is simple:
Transactions
(
ID INT,
TransactionDate DATETIME,
SalesAmount MONEY
)
I want the results to look similar to ExcelSheet below (I am showing only 2017/2018 amounts, but actual query needs to return results for all available years according to TransactionDate)
This is aggregation and a cumulative sum:
select year(TransactionDate), month(TransactionDate),
sum(SalesAmount),
sum(sum(SalesAmount)) over (partition by year(TransactionDate) order by min(TransactionDate))
from Transactions
group by year(TransactionDate), month(TransactionDate)
order by year(TransactionDate), month(TransactionDate);
Try it:
With Q
as
(
Select DatePart(yyyy,TransactionDate) 'Year',DatePart(m,TransactionDate) 'Month', sum(SalesAmount) 'Sales'
From Transactions
Group by DatePart(yyyy,TransactionDate),DatePart(m,TransactionDate)
)
Select q.Year,q.Month,q.sales,( Select sum(q1.Sales)
From Q q1
Where q1.Year=q.Year
And q1.Month <= q.Month
) 'Cumulative Sale'
From Q q
Order by q.Year,q.Month
Try this:
with cte as
(
select year(TransactionDate) as Year, month(TransactionDate) as Month, SalesAmount
)
select a.Year, a.Month, a.SalesAmount, sum(b.SalesAmount) as cumulativeSalesAmount
from Transactions a inner join Transactions b on a.STORE_ID = b.STORE_ID and a.Year = b.Year and a.Month >= b.Month
group by a.Year, a.Month
order by 1, 2

SUM and Grouping by date and material

Still learning SQL forgive me.
I have 3 tables. a material table, a material_req table and a material_trans table. I want to group by material and then group columns by year.
so it would be [material, 2019, 2018, 2017, 2016, total (total being the total qty used for each material.
I have tried to place the date in the select statement, and grouped by the date also. but then the returned result is a lot of the same material with a lot of dates. I only need the year. maybe try the same and return just the year?
SELECT material_req.Material
-- , Material_Trans_Date
, SUM(-1 * material_trans.Quantity) AS 'TOTAL'
,Standard_Cost
FROM
Material_Req inner join Material_Trans
ON
Material_Req.Material_Req = Material_Trans.Material_Req
LEFt JOIN Material
ON
Material.Material = Material_Req.Material
WHERE
material_trans.Material_Trans_Date between '20180101' AND GETDATE()
-- Material_Trans_Date between '20180101' AND '20181231'
-- Material_Trans_Date between '20170101' AND '20171231'
-- Material_Trans_Date between '20160101' AND '20161231'
GROUP BY
material_req.Material ,Standard_Cost
ORDER BY
Material_Req.Material, Standard_Cost
expected results should by grouped by material, 2019, 2018, 2017,2016, Standard_Cost. the years column will have the sum of qty for each material for that year.
results look like this current_results
If you are using SQL Server then you might try this:
SELECT material_req.Material
, SUM(CASE WHEN DATEPART(YEAR, Material_Trans_Date) = '2019' THEN material_trans.Quantity ELSE 0 END) [2019 TOTAL]
, SUM(CASE WHEN DATEPART(YEAR, Material_Trans_Date) = '2018' THEN material_trans.Quantity ELSE 0 END) [2018 TOTAL]
,Standard_Cost
FROM
Material_Req inner join Material_Trans
ON
Material_Req.Material_Req = Material_Trans.Material_Req
LEFt JOIN Material
ON
Material.Material = Material_Req.Material
WHERE
material_trans.Material_Trans_Date between '20180101' AND GETDATE()
GROUP BY
material_req.Material ,Standard_Cost
ORDER BY
Material_Req.Material, Standard_Cost

How can I SELECT rows with MAX(Column value)

SELECT
DATEPART(YEAR, tblGRN.GRNApproveDate) AS Year,
tblGRNMaterials.MaterialCode,
tblMaterial.MaterialDescription,
SUM(tblGRNMaterials.NetQty) AS Qty
FROM
tblGRN
INNER JOIN
tblGRNMaterials ON tblGRN.GRNNO = tblGRNMaterials.GRNNO
INNER JOIN
tblMaterial ON tblGRNMaterials.MaterialCode = tblMaterial.MaterialCode
WHERE
(tblGRN.GRNStoreID = 'RM_Main')
AND (tblGRN.GRNStatus = 1)
AND (CONVERT(DATE, tblGRN.GRNApproveDate) BETWEEN '2017-01-01' AND '2018-12-31')
GROUP BY
tblGRNMaterials.MaterialCode, tblMaterial.MaterialDescription,
DATEPART(YEAR, tblGRN.GRNApproveDate)
ORDER BY
tblGRNMaterials.MaterialCode
My output
Year MaterialCode MaterialDescription Qty
-------------------------------------------------------------
2017 LM/CCM/SO Cellulose C. Methyl 200.000
2018 LM/CCM/SO Cellulose C. Methyl 350.000
2017 LM/MAG/PW Magnesium Stearate 175.000
2018 LM/MAG/PW Magnesium Stearate 250.000
2017 LM/MCC/PW Micro Crystal Cellulose 75.000
2018 LM/MCC/PW Micro Crystal Cellulose 0.320
I need to select each year holding the maximum value of 'Qty', comparison with year 2017 and 2018
Result should be:
Year MaterialCode MaterialDescription Qty
----------------------------------------------------------
2018 LM/CCM/SO Cellulose C. Methyl 350.000
2018 LM/MAG/PW Magnesium Stearate 250.000
2017 LM/MCC/PW Micro Crystal Cellulose 75.000
First, I would write the query like this:
SELECT year(g.GRNApproveDate) AS Year, gm.MaterialCode,
m.MaterialDescription, SUM(gm.NetQty) AS Qty
FROM tblGRN g INNER JOIN
tblGRNMaterials gm
ON g.GRNNO = gm.GRNNO INNER JOIN
tblMaterial m
ON gm.MaterialCode = m.MaterialCode
WHERE g.GRNStoreID = 'RM_Main' AND
g.GRNStatus = 1 AND
g.GRNApproveDate >= '2017-01-01' AND
g.GRNApproveDate < '2019-01-01'
GROUP BY gm.MaterialCode, m.MaterialDescription, year(g.GRNApproveDate)
ORDER BY gm.MaterialCode;
Although not the most performant method, probably the simplest is:
SELECT TOP (1) WITH TIES, year(g.GRNApproveDate) AS Year, gm.MaterialCode,
m.MaterialDescription, SUM(gm.NetQty) AS Qty
FROM tblGRN g INNER JOIN
tblGRNMaterials gm
ON g.GRNNO = gm.GRNNO INNER JOIN
tblMaterial m
ON gm.MaterialCode = m.MaterialCode
WHERE g.GRNStoreID = 'RM_Main' AND
g.GRNStatus = 1 AND
g.GRNApproveDate >= '2017-01-01' AND
g.GRNApproveDate < '2019-01-01'
GROUP BY gm.MaterialCode, m.MaterialDescription, year(g.GRNApproveDate)
ORDER BY ROW_NUMBER() OVER (PARTITION BY gm.MaterialCode ORDER BY SUM(gm.NetQty) DESC);

how to use multiple sum and group by in subquery?

ER DIAGRAM SNAP have to Find the Order Amount Total for 2 type of orders for each year.
table is SalesOrderHeader
Subtotal + TaxAmt gives the total order amount
OnlineOrderFlag(0/1 is direct/online respectively)
1>Display the results in the below formats
OrderYear Direct Online
2001 75423 344344
2002
2003
2004
SQL:
select year(a.OrderDate),
( select SUM(SubTotal+TaxAmt) FROM SalesOrderHeader b WHERE OnlineOrderFlag = 0 group by year(b.OrderDate) ) as tot ,
( select SUM(SubTotal+TaxAmt) FROM SalesOrderHeader c WHERE OnlineOrderFlag = 1 group by year(c.OrderDate) ) as tt
FROM SalesOrderHeader a inner join SalesOrderHeader b
on b.SalesOrderID = a.SalesOrderID
inner join
SalesOrderHeader c on c.SalesOrderID = a.SalesOrderID
can someone please tel how to proceed further? i'm stuck at this
2> and also how to find it in the below format ?
OnlineFlag Year TotalAmt
Direct 2001
Direct 2002
Direct 2003
Direct 2004
Online 2001
Online 2002
Online 2003
Online 2004
This should work. Added the inner subquery to make it clear where the group by needs to go and to add the subtotal and tax for each record before summarizing.
select a.year
,SUM(Case when a.OnlineOrderFlag = 1 THEN a.total else null end) as Direct
,SUM(Case when a.OnlineOrderFlag = 0 THEN a.total else null end) as Online
FROM (select year(OrderDate) as year, (SubTotal+TaxAmt) as total, OnlineOrderFlag
from SalesOrderHeader) a
Group by a.year
SELECT YEAR(ORDERDATE), ONLINEORDERFLAG,
SUM(SUBTOTAL) SUBTOTAL,SUM(TAXAMT) TAXAMT,
SUM(SUBTOTAL + TAXAMT) TOTALDUE
FROM SALESORDERHEADER
WHERE ONLINEORDERFLAG = 1
GROUP BY YEAR(ORDERDATE) WITH ROLLUP
UNION
SELECT YEAR(ORDERDATE), ONLINEORDERFLAG,
SUM(SUBTOTAL) ,SUM(TAXAMT),
SUM(SUBTOTAL + TAXAMT)
FROM SALESORDERHEADER
WHERE ONLINEORDERFLAG = 0
GROUP BY YEAR(ORDERDATE) WITH ROLLUP
;

SQL Server : Counts/Group By

I have an orders table that I need to generate a report from that groups by month/year, showing the total orders for the month, and the number actually received.
This gives me total # of orders by month/year:
SELECT YEAR(o.OrderDate) As 'Year'
, MONTH(o.OrderDate) As 'Month'
, COUNT(ID) As 'OrderCount'
FROM Orders o
GROUP BY YEAR(o.OrderDate), MONTH (o.OrderDate)
ORDER BY YEAR(o.OrderDate) DESC, MONTH (o.OrderDate) DESC
This gives me total # of orders RECEIVED by month/year:
SELECT YEAR(o.OrderDate) As 'Year'
, MONTH(o.OrderDate) As 'Month'
, COUNT(o.ID) As 'OrderReceivedCount'
FROM Orders o
INNER JOIN OrderStatus s ON s.ID = o.CurrentStatus
WHERE s.StatusPriority > 4 AND s.IsCancelled = 0
GROUP BY YEAR(o.OrderDate), MONTH (o.OrderDate)
ORDER BY YEAR(o.OrderDate) DESC, MONTH (o.OrderDate) DESC
But how can I combine that into one query? I can't work out how the 'group by' would work?
I think you want something like:
SELECT YEAR(o.OrderDate) As [Year]
, MONTH(o.OrderDate) As [Month]
, COUNT(*) As OrderCount
, SUM(CASE
WHEN s.StatusPriority > 4 AND
s.IsCancelled = 0 THEN 1
ELSE 0 END) as OrderReceivedCount
FROM Orders o
INNER JOIN OrderStatus s ON s.ID = o.CurrentStatus
GROUP BY YEAR(o.OrderDate), MONTH (o.OrderDate)
ORDER BY YEAR(o.OrderDate) DESC, MONTH (o.OrderDate) DESC
That is join all of the orders to their statuses, whatever they may be, and then do a conditional count of those (via SUM/CASE) to work out which ones have been received.