Access SQL query - Percentage of Total calculation - sql

In Access SQL, I am attempting what should seem like a simple task in attaining a percentage of total. There are 3 item stores (Sears, kmart & Mktpl) of which in any given week, I wish to calculate their respective percent of total based on balance of sales (all can be obtained using one table - tbl_BUChannelReporting).
For example week 5 dummy numbers - Sears 7000, kmart 2500, mktpl 2000
the following ratios would be returned: sears 61%, kmart 22%, mktpl 17%
I was originally trying to create a sub query and wasn't getting anywhere so I am essentially trying to sum sales on one of the item stores in week 5 divided by the sum of all 3 item store sales in week 5. The following is my query, which is giving me "cannot have aggregate function in expression" error:
SELECT FY, FW, Rept_Chnl, BU_NM, Order_Store, Item_Store, CDBL(
SUM(IIF([item_store]="sears", revenue, IIF([item_store]="kmart", revenue, IIF([item_store]="mktpl", revenue,0)))) /
(SUM(IIF([item_store]="sears",revenue,0)+SUM(IIF([item_store]="kmart",revenue,0)+SUM(IIF([item_store]="mktpl",revenue,0))))))
AS Ratios
FROM tbl_BUChannelReporting
WHERE FY = "2017"
AND FW = 5
GROUP BY FY, FW, Rept_Chnl, BU_NM, Order_Store, item_store
Thanks all in advance for taking the time. This is my 1st post here and I don't consider myself anything but a newbie anxious to learn from the best and see how this turns out.
Take care!
-D

Consider using two derived tables or saved aggregate queries: one that groups on Item_Store and the other that does not include Item_Store in order to sum the total stores' revenue. All other groupings (FY, FW, Rept_Chnl, BU_NM, Order_Store) remain in both and used to join the two. Then in outer query, calculate percentage ratio.
SELECT i.*, CDbl(i.Store_Revenue / a.Store_Revenue) As Ratios
FROM
(SELECT t.FY, t.FW, t.Rept_Chnl, t.BU_NM, t.Order_Store, t.Item_Store,
SUM(t.Revenue) As Store_Revenue
FROM tbl_BUChannelReporting t
WHERE t.FY = '2017' AND t.FW = 5
GROUP BY t.FY, t.FW, t.Rept_Chnl, t.BU_NM, t.Order_Store, t.Item_Store) As i
INNER JOIN
(SELECT t.FY, t.FW, t.Rept_Chnl, t.BU_NM, t.Order_Store
SUM(t.Revenue) As Store_Revenue
FROM tbl_BUChannelReporting t
WHERE t.FY = '2017' AND t.FW = 5
GROUP BY t.FY, t.FW, t.Rept_Chnl, t.BU_NM, t.Order_Store) As a
ON i.FY = a.FY AND i.FW = a.FW AND i.Rept_Chnl = a.Rept_Chnl
AND i.BU_NM = a.BU_NM AND i.Order_Store = a.Order_Store
Or save each above SELECT statement as its own query and reference both below:
SELECT i.*, (i.Store_Revenue / a.Store_Revenue) As Ratios
FROM
Indiv_Item_StoreAggQ As i
INNER JOIN
All_Item_StoreAggQ As a
ON i.FY = a.FY AND i.FW = a.FW AND i.Rept_Chnl = a.Rept_Chnl
AND i.BU_NM = a.BU_NM AND i.Order_Store = a.Order_Store

Related

MS Access Query - Display All Rows from Original Joined Table

I need to write a query that displays ALL revenue centers for a month whether they have revenue or not. This seems like a simple request but I have seemed to hit a brick wall. Below is my SQL:
SELECT ID_ItemNominal, ItemNominal_Description, Sum(Nz([ITM_Net],0)) AS ITM_Net_Total
FROM TSub_ItmNominal LEFT JOIN (T_Invoice RIGHT JOIN T_LineItems ON T_Invoice.ITM_Reference = T_LineItems.ITM_Reference) ON TSub_ItmNominal.ID_ItemNominal = T_LineItems.ITM_Nominal
WHERE (((Year([ITM_Date]))=[report_year] Or (Year([ITM_Date])) Is Null) AND ((Month([ITM_Date]))=[report_month]))
GROUP BY TSub_ItmNominal.ID_ItemNominal, TSub_ItmNominal.ItemNominal_Description
HAVING (((TSub_ItmNominal.ID_ItemNominal) Like "4*"))
ORDER BY TSub_ItmNominal.ID_ItemNominal;
ID_ItemNominal = the Integer code for the Revenue Center
ItemNominal_Description = the description of the Revenue Center
ITM_Net = the Currency amount for the Line Item on the Invoice, to be SUM for a month total
ITM_ Date = the Date of the Invoice
My thought was to use the LEFT JOIN to say that I want to see ALL of the revenue centers, even if those records do not have any data for that month. What I get is the centers that DO have revenue for the year but DO NOT have revenue for the month are not shown / filtered out.
What the Current query provides:
40500 | Sales - Digital | $###.##
40700 | Sales - Misc | $###.##
40800 | Sales - Mail | $###.##
40900 | Sales - Clothing| $0.00
We have not done any revenue under 40900 this year so far so it shows as a result in the query. We have done revenue in 40600 this year but not for the month of April. The 40600 seems to be filtered out by the WHERE part of the query as well as any other revenue centers that we have revenue for the year but not the selected date.
I would like to see these revenue centers included in the query but show as $0.00 for the month.
Any help would be greatly appreciated, I feel like I am close but I just can't seem to get the correct results. Thank you in advance!
You could join the original table with all rows and join your query to it like
SELECT t1.ID_ItemNominal, t1.ItemNominal_Description,t2.ITM_Net_Total
FROM TSub_ItmNominal AS t1 LEFT JOIN (SELECT ID_ItemNominal, ItemNominal_Description, Sum(Nz([ITM_Net],0)) AS ITM_Net_Total
FROM TSub_ItmNominal LEFT JOIN (T_Invoice RIGHT JOIN T_LineItems ON T_Invoice.ITM_Reference = T_LineItems.ITM_Reference) ON TSub_ItmNominal.ID_ItemNominal = T_LineItems.ITM_Nominal
WHERE (((Year([ITM_Date]))=[report_year] Or (Year([ITM_Date])) Is Null) AND ((Month([ITM_Date]))=[report_month]))
GROUP BY TSub_ItmNominal.ID_ItemNominal, TSub_ItmNominal.ItemNominal_Description
HAVING (((TSub_ItmNominal.ID_ItemNominal) Like "4*")) ) AS t2 ON t1.ID_ItemNominal = t2.ID_ItemNominal
WHERE ((([t1l].[ID_ItemNominal]) Like "4*"))
ORDER BY t1.ID_ItemNominal;
Usually, when you run LEFT JOIN + WHERE you run an analogous INNER JOIN. But according to your specifications, the sub items table should be optionally joined since it can contain actual sales data not exhaustive of all revenue centers.
Therefore, run the WHERE filtering within a subquery and then have this subquery left joined to main set of revenue centers. Also, for readability below converts RIGHT JOIN to LEFT JOIN and uses table aliases instead of full table names.
SELECT main.ITM_Nominal,
main.ItemNominal_Description,
SUM(NZ(sub.[ITM_Net], 0)) AS ITM_Net_Total
FROM (T_LineItems AS main
LEFT JOIN T_Invoice AS inv
ON inv.ITM_Reference = main.ITM_Reference)
LEFT JOIN (
SELECT ID_ItemNominal, [ITM_Net]
FROM TSub_ItmNominal
WHERE ID_ItemNominal ALIKE '4%'
AND YEAR([ITM_Date]) = [report_year]
AND MONTH([ITM_Date]) = [report_month]
) AS sub
ON sub.ID_ItemNominal = main.ITM_Nominal
GROUP BY main.ITM_Nominal,
main.ItemNominal_Description
ORDER BY main.ITM_Nominal;

Query for remaining balance

Query for remaining balance
I am using SQLITE 3.1.1
The scenario is the ff:
Let us say Total Quantity is 11.
The formula should be:
Total Quantity - Quantity Used = Remaining
It should look like this:
First: 11 - 1 = 10
Second: 10- 6 = 4
Third: 4 - 0 = 4
and so on..
Expected Result:
Also, Remaining value can't be lower than 0.
I currently have this SQL query but it doesn't get the Remaining query result for the next transaction but rather it always starts with Total Quantity.
SELECT
filter_maintenance.maintenance_id,
filter_maintenance.stock_id,
filter_maintenance.quantity_used,
filter_maintenance.date_registered,
filter_maintenance.date_changed,
inventories.stock_name,
SUM(inventories_order.order_quantity) - filter_maintenance.quantity_used AS Remaining
FROM filter_maintenance
INNER JOIN inventories ON filter_maintenance.stock_id = inventories.stock_id
INNER JOIN inventories_order ON filter_maintenance.stock_id = inventories_order.stock_id
GROUP BY filter_maintenance.maintenance_id
This is the output I currently have:
Your help is greatly appreciated. Thank you in advance.
Since you are using sqllite and there are no window functions you need to use a self-join instead. I assume maintenance_id is a primary key in filter_maintenance.
SELECT
filter_maintenance.maintenance_id,
filter_maintenance.stock_id,
filter_maintenance.quantity_used,
filter_maintenance.date_registered,
filter_maintenance.date_changed,
inventories.stock_name,
sum(inventories_order.order_quantity) - filter_maintenance.sum_quantity_used AS Remaining
FROM
(
SELECT fm1.*,
sum(fm2.quantity_used) AS sum_quantity_used
FROM filter_maintenance fm1
INNER JOIN filter_maintenance fm2 ON fm1.stock_id = fm2.stock_id and
fm1.date_registered >= fm2.date_registered
GROUP BY fm1.maintenance_id
) filter_maintenance
INNER JOIN inventories ON filter_maintenance.stock_id = inventories.stock_id
INNER JOIN inventories_order ON filter_maintenance.stock_id = inventories_order.stock_id
GROUP BY filter_maintenance.maintenance_id

How to using subquery values in arithmetic operations

My manager wants to see what is total values of our suppliers shipments, and what is the total values of their invoices recorded. So he can see the differencies and want from suppliers to unsended invoices.
Here is my code.
It is working on accounting table and shipment detail table.
fis_meblag0 is always little from zero because it is 320 account so I mutiply it -1 for get real value.
sth_tutar is value of shipment, sth_vergi is VAT and so the sum of them is equal to sum of total with VAT.
Now the hard part.
Manager wants to diference between them in a other column and also sort the valuez z to a.
I know I can reuse same subselect for the getting totals but I want to know that can I achieve this without using the same subquery again.
I mean in first subselect I have the total, in last column I only need just the total, can I use total without compute it again?
Regards
select
ch.cari_kod as Carikod,
ch.cari_unvan1 as Unvani,
(select (sum(mf.fis_meblag0) * -1)
from dbo.MUHASEBE_FISLERI mf
where (mf.fis_tarih > '20141231' and mf.fis_tarih < '20150201')
and mf.fis_hesap_kod = ch.cari_kod
and mf.fis_meblag0 < 0) as mtoplam,
(Select sum (sth.sth_tutar + sth.sth_vergi)
from dbo.STOK_HAREKETLERI sth
where (sth.sth_tarih > '20141231' and sth.sth_tarih < '20150201')
and sth.sth_cari_kodu = ch.cari_kod
and sth.sth_normal_iade = 0
and sth.sth_tip = 0) as stoplam
from
dbo.CARI_HESAPLAR ch
where
ch.cari_kod like '320%'
try this query:
select Carikod, Unvani, mtoplam, stoplam, mtoplam - stoplam as Grand_total
from
(
-- your full query here
) T

SQL SUM total using 2 tables

I have 2 tables: TBL_EQUIPMENTS and TBL_PROPOSAL.
TBL_PROPOSAL has 3 important columns:
id_proposal
date
discount
TBL_EQUIPMENTS has:
id_equipment
id_proposal
unit_price
quantity
Now I want to know how much (in €) is my proposals for this year, let's say:
For each TBL_PROPOSAL.date > "2013-01-01" I want to use the formula:
result = (TBL_EQUIPMENTS.unit_price * TBL_EQUIPMENTS.quantity) * (100 - TBL_PROPOSAL.discount)
I can do this with one SQL statement?
Yes you can:
select e.unit_price * e.quantity) * (100 - p.discount)
from tbl_Proposal p join
tbl_Equipments e
on p.id_Proposal = e.id_proposal
where date >= '2013-01-01'
The basic syntax is for a join. The p and e are called table aliases. They make the query easier to read (the full table names are rather bulky).
Date operations differ among databases. The last statement should work in most databases. However, you might try one of the following as well:
where year(date) = 2013
where extract(year from date) = 2013

SP Previous year sales data from given date

How to show current year data and previous Data in two column SQL Server 2000
Below Procedure shows my Given date Data I want to set Previous year data from given date in other column
SELECT TOP 100 PERCENT
dbo.SI_Item.ig2_Code, dbo.SI_ItemGroup2.ig2_Desc,
SUM(SI_InvoiceDetail.invcd_Rate * dbo.SI_InvoiceDetail.invcd_Qty -
dbo.SI_InvoiceDetail.invcd_DiscountAmt) AS Total
FROM
dbo.SI_InvoiceDetail
INNER JOIN
dbo.SI_Item ON dbo.SI_InvoiceDetail.itm_ItemCode = dbo.SI_Item.itm_ItemCode
INNER JOIN
dbo.SI_InvoiceMaster ON dbo.SI_InvoiceDetail.invcm_CoCode = dbo.SI_InvoiceMaster.invcm_CoCode AND
dbo.SI_InvoiceDetail.invcm_BrCode = dbo.SI_InvoiceMaster.invcm_BrCode AND
dbo.SI_InvoiceDetail.invcm_SiteCode = dbo.SI_InvoiceMaster.invcm_SiteCode AND
dbo.SI_InvoiceDetail.invcm_Year = dbo.SI_InvoiceMaster.invcm_Year AND
dbo.SI_InvoiceDetail.invcm_Period = dbo.SI_InvoiceMaster.invcm_Period AND
dbo.SI_InvoiceDetail.docs_DocCode = dbo.SI_InvoiceMaster.docs_DocCode AND
dbo.SI_InvoiceDetail.doctyp_Code = dbo.SI_InvoiceMaster.doctyp_Code AND
dbo.SI_InvoiceDetail.invcm_DocNo = dbo.SI_InvoiceMaster.invcm_DocNo
INNER JOIN
dbo.SI_ItemGroup2 ON dbo.SI_Item.ig2_Code = dbo.SI_ItemGroup2.ig2_Code
WHERE (dbo.SI_InvoiceDetail.docs_DocCode = 'inv') AND
(dbo.SI_InvoiceDetail.itm_ItemCode BETWEEN '0101010000001' AND '0301020004001') AND
(dbo.SI_InvoiceMaster.invcm_Date BETWEEN #Invcm_date_from AND #Invcm_date_to)
GROUP BY dbo.SI_Item.ig2_Code ,SI_ItemGroup2.ig2_Desc
Resolved it 70% by changing in Query as below
SELECT TOP 100 PERCENT dbo.SI_Item.ig2_Code, dbo.SI_ItemGroup2.ig2_Desc,year(dbo.SI_InvoiceMaster.invcm_Date) AS SalesYear,
&
Group By Year(dbo.SI_InvoiceMaster.invcm_Date),dbo.SI_Item.ig2_Code ,SI_ItemGroup2.ig2_Desc
ORDER BY Year(dbo.SI_InvoiceMaster.invcm_Date) ,dbo.SI_Item.ig2_Code
but its works but not as i want because its showing year in Row and User mut inpuer date range of aboce 2 years then will show.
if anyone Got Proper solution do share please