so I've to gather the data from the table such that
1.Group each order by shipment type.
2.Filter orders for which sum of sales at shipping group level is less than $35 however overall sales is greater than $35.
For eg: If an order has two shipping groups: S2H and SDD.
Then:
S2H = $20
SDD = $25
Order total = $45
In the above example the individual shipment total is less than $35, however order total is greater than $35.
I've tried till here and would like to know how can I move forward from here to get the desirable date:
SELECT
(CASE WHEN Sales > 35 AND Digital = 0 AND SDD = 1 AND BOPS = 0 AND S2H = 0 AND PREORDER = 0 THEN order_no
ELSE NULL END) AS Above_SDD_Order,
(CASE WHEN Sales <= 35 AND Digital = 0 AND SDD = 1 AND BOPS = 0 AND S2H = 0 AND PREORDER = 0 THEN order_no
ELSE NULL END) AS Below_SDD_Order,
(CASE WHEN Sales > 35 AND Digital = 1 AND SDD = 1 AND BOPS = 0 AND S2H = 1 AND PREORDER = 0 THEN order_no
ELSE NULL END) AS Above_SDD_S2H_Digital_Order,
(CASE WHEN Sales <= 35 AND Digital = 1 AND SDD = 1 AND BOPS = 0 AND S2H = 1 AND PREORDER = 0 THEN order_no
ELSE NULL END) AS Below_SDD_S2H_Digital_Order,
(CASE WHEN Sales > 35 AND Digital = 0 AND SDD = 1 AND BOPS = 0 AND S2H = 1 AND PREORDER = 0 THEN order_no
ELSE NULL END) AS Above_S2H_SDD_Order,
(CASE WHEN Sales <= 35 AND Digital = 0 AND SDD = 1 AND BOPS = 0 AND S2H = 1 AND PREORDER = 0 THEN order_no
ELSE NULL END) AS Below_SDD_S2H_Order,
(CASE WHEN Sales > 35 AND Digital = 0 AND SDD = 1 AND BOPS = 0 AND S2H = 0 AND PREORDER = 1 THEN order_no
ELSE NULL END) AS Above_Preorder_SDD_Order,
(CASE WHEN Sales <= 35 AND Digital = 0 AND SDD = 1 AND BOPS = 0 AND S2H = 0 AND PREORDER = 1 THEN order_no
ELSE NULL END) AS Below_Preorder_SDD_Order,
(CASE WHEN Sales <= 35 AND Digital = 1 AND SDD = 1 AND BOPS = 0 AND S2H = 0 AND PREORDER = 0 THEN order_no
ELSE NULL END) AS Below_Digital_SDD_Order,
(CASE WHEN Sales > 35 AND Digital = 1 AND SDD = 1 AND BOPS = 0 AND S2H = 0 AND PREORDER = 0 THEN order_no
ELSE NULL END )AS Above_Digital_SDD_Order,
(CASE WHEN Sales <= 35 AND Digital = 0 AND SDD = 1 AND BOPS = 1 AND S2H = 0 AND PREORDER = 0 THEN order_no
ELSE NULL END) AS Below_BOPS_SDD_Order,
(CASE WHEN Sales > 35 AND Digital = 0 AND SDD = 1 AND BOPS = 1 AND S2H = 0 AND PREORDER = 0 THEN order_no
ELSE NULL END) AS Above_BOPS_SDD_Order,
(CASE WHEN Sales <= 35 AND Digital = 1 AND SDD = 1 AND BOPS = 1 AND S2H = 0 AND PREORDER = 0 THEN order_no
ELSE NULL END )AS Below_Digital_BOPS_SDD_Order,
(CASE WHEN Sales > 35 AND Digital = 1 AND SDD = 1 AND BOPS = 1 AND S2H = 0 AND PREORDER = 0 THEN order_no ELSE NULL END )AS Above_Digital_BOPS_SDD_Order
FROM
(SELECT order_no,
MAX(CASE WHEN (Shipping_Group = 'DIGITAL_GIFT_CARD' OR Shipping_Group = 'DIGITAL' OR Shipping_Group = 'GAME_INFORMER_DIGITAL' OR Shipping_Group = 'LOYALTY') THEN 1 ELSE 0 END ) AS Digital,
MAX(CASE WHEN Shipping_Group = 'GAME_INFORMER_PHYSICAL' OR Shipping_Group = 'PHYSICAL' THEN 1 ELSE 0 END) AS S2H,
MAX(CASE WHEN Shipping_Group = 'PHYSICAL_PREORDER' OR Shipping_Group = 'DIGITAL_PREORDER' OR Shipping_Group = 'PICKUP_PREORDER' THEN 1 ELSE 0 END ) AS Preorder,
MAX(CASE WHEN Shipping_Group = 'PICKUP' THEN 1 ELSE 0 END ) AS BOPS,
MAX(CASE WHEN Shipping_Group = 'SDD' THEN 1 ELSE 0 END) AS SDD,
SUM(pl_net_price) as Sales
From
(SELECT order_no, Shipping_Group,pl_net_price
FROM
eim-prod.EDW_VIEWS.ORDER_SUBMIT_PRODUCT_LINEITEM
)
group by 1)
group by 1,2,3,4,5,6,7,8,9,10,11,12,13,14;
You can also tell me if my approach is wrong and how I should take it further as I am a newbie with SQL. Thanks
Related
Can someone please help me with this issue? I've scoured the Internet looking at dozens of examples, but i just can't find a solution that works.
I am using Access 2013. The problem is that I am trying to make a query that will highlight all part numbers from a supplier that either has customer back orders and/or overdue deliveries.
I am using three tables:
tbl_Inventory_Master which I require the part number, on hand stock value, and the supplier code.
For any back orders I need to join the tbl_Customer_Back_Order table as I need the count of back order lines and the sum of the back order quantity.
If the supplier has a late delivery, then I need to add the tbl_On_Order table showing the count of overdue deliveries and the sum of the overdue quantities.
The query is retrieving the data but the returned quantities are double what they should be.
SELECT
I.Inventory_Part_Num, I.Description, I.On_Hand_Stock,
COUNT (B.Part_Number) AS Back_Order_Count, SUM(B.Back_Order_Qty) as BO_Qty,
COUNT(O.Part_Number) AS Late_Deliveries_Count, SUM(O.Order_Qty) AS Late_Qty
FROM (tbl_Inventory_Master AS I
LEFT OUTER JOIN tbl_Customer_Back_Order AS B
ON I.Inventory_Part_Num = B.Part_Number)
LEFT OUTER tbl_On_Order AS O
ON I.Inventory_Part_Num = O.Part_Number
WHERE
I.Customer_Code = '274' AND
O.Due_Date < [ENTER TODAYS DATE IN FORMAT DD/MM/YYYY]
GROUP BY I.Inventory_Part_Num, I.Description, I.On_Hand_Stock
For example, for the part number 2022940 I should have 10 back order lines and an overdue quantity of 43. Instead, the query is returning 20 back order lines and an overdue quantity sum of 86.
From the on order table I have three orders totaling 144 pieces, instead the query is returning 960.
Can someone please advise, as this is driving me crazy?
You are joining along unrelated dimensions, so you need to aggregate before joining:
SELECT I.Inventory_Part_Num, I.Description, I.On_Hand_Stock,
B.Back_Order_Count, B.BO_Qty,
O.Late_Deliveries_Count, O.Late_Qty
FROM (tbl_Inventory_Master AS I LEFT OUTER JOIN
(SELECT B.Part_Number, COUNT(*) as Back_Order_Count,
SUM(B.Back_Order_Qty) as BO_Qty
FROM tbl_Customer_Back_Order AS B
GROUP BY B.Part_Number
) as B
ON I.Inventory_Part_Num = B.Part_Number
) LEFT JOIN
(SELECT O.Part_Number, COUNT(O.Part_Number) AS Late_Deliveries_Count,
SUM(O.Order_Qty) AS Late_Qty
FROM tbl_On_Order AS O
WHERE O.Due_Date < [ENTER TODAYS DATE IN FORMAT DD/MM/YYYY]
GROUP BY O.Part_Number
) as O
ON I.Inventory_Part_Num = O.Part_Number
WHERE I.Customer_Code = '274';
Notice the outer aggregation is no longer needed.
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
the data that is created has summary totals like Invoice Amount. Now we don't want invamt but the invamt without the freight charges. Each detail row has a part#, qty, and sale price. We need to join det_table on the otord# = idord#.
But also to sum the det_table, per order, the idprt# must not start with 'FRT' thats how we know freight. I am not sure what sort of join i think left outer.
I then need to include in the first line below, the (qty* sale_price as lintot where idprt# does not start with 'FRT') but then also sum this lintot for the order#.
CREATE VIEW CLSPAYTP AS SELECT OTCOM#, OTORD#, OTTRND, OTTRT, INVAMT,
IHORG$, IHORD$, IHINV#,
OTUSRN, OTTRNC, IHPTTC, IHSLR#, IHORDT,
IHDOCD, RFCAT, RFSLC,
RFSQ2, RFDTA
FROM AZLIB.CLSPAYTPP
WHERE
OTTRNC='001'
UNION
SELECT
OTCOM#, OTORD#, OTTRND, OTTRT, INV
INVAMT, IHORG$, IHORD$,IHINV#, OTUSRN, OTTRNC, IHPTTC,
IHSLR#, IHORDT,
IHDOCD, RFCAT, RFSLC, RFSQ2, RFDTA FROM
AZLIB.CLSPAYTPP OT1
WHERE OTTRT = (SELECT MIN(OTTRT)
FROM AZLIB.CLSPAYTPP OT2
WHERE OT2.OTTRNC<>'001' AND OT1.OTORD#= OT2.OTORD#
GROUP BY OT2.OTORD#)
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
Following on from my previous question at When is a groupby query evaluated in RavenDB? I decided to completely restructure the data into a format that is theoretically easier to query on.
Having now created the new data structure, I am struggling to find how to query it.
It took me 30 seconds to write the following SQL query which gives me exactly the results I need:
SELECT GroupCompanyId, AccountCurrency, AccountName, DATEPART(year, Date) AS Year,
(SELECT SUM(Debit) AS Expr1
FROM Transactions AS T2
WHERE (T1.GroupCompanyId = GroupCompanyId) AND (T1.AccountCurrency = AccountCurrency) AND (T1.AccountName = AccountName) AND (DATEPART(year,
Date) < DATEPART(year, T1.Date))) AS OpeningDebits,
(SELECT SUM(Credit) AS Expr1
FROM Transactions AS T2
WHERE (T1.GroupCompanyId = GroupCompanyId) AND (T1.AccountCurrency = AccountCurrency) AND (T1.AccountName = AccountName) AND (DATEPART(year,
Date) < DATEPART(year, T1.Date))) AS OpeningCredits, SUM(Debit) AS Db, SUM(Credit) AS Cr
FROM Transactions AS T1
WHERE (DATEPART(year, Date) = 2011)
GROUP BY GroupCompanyId, AccountCurrency, AccountName, DATEPART(year, Date)
ORDER BY GroupCompanyId, AccountCurrency, Year, AccountName
So far I have got the Map/Reduce as follows, which from Studio appears to give the correct results - i.e. it breaks down and groups the data by date.
public Transactions_ByDailyBalance()
{
Map = transactions => from transaction in transactions
select new
{
transaction.GroupCompanyId,
transaction.AccountCurrency,
transaction.Account.Category,
transaction.Account.GroupType,
transaction.AccountId,
transaction.AccountName,
transaction.Date,
transaction.Debit,
transaction.Credit,
};
Reduce = results => from result in results
group result by new
{
result.GroupCompanyId,
result.AccountCurrency,
result.Category,
result.GroupType,
result.AccountId,
result.AccountName,
result.Date,
}
into g
select new
{
GroupCompanyId = g.Select(x=>x.GroupCompanyId).FirstOrDefault(),
AccountCurrency = g.Select(x=>x.AccountCurrency).FirstOrDefault(),
Category=g.Select(x=>x.Category).FirstOrDefault(),
GroupType=g.Select(x=>x.GroupType).FirstOrDefault(),
AccountId = g.Select(x=>x.AccountId).FirstOrDefault(),
AccountName=g.Select(x=>x.AccountName).FirstOrDefault(),
Date=g.Select(x=>x.Date).FirstOrDefault(),
Debit=g.Sum(x=>x.Debit),
Credit=g.Sum(x=>x.Credit)
};
Index(x=>x.GroupCompanyId,FieldIndexing.Analyzed);
Index(x=>x.AccountCurrency,FieldIndexing.Analyzed);
Index(x=>x.Category,FieldIndexing.Analyzed);
Index(x=>x.AccountId,FieldIndexing.Analyzed);
Index(x=>x.AccountName,FieldIndexing.Analyzed);
Index(x=>x.Date,FieldIndexing.Analyzed);
}
}
However, I can't work out how to query the data at one go.
I need the opening balance as well as the period balance, so I ended up writing this query which takes as a parameter the account. Following on from Oren's comments to my previous question, that I was mixing Linq with Lucene query, having rewritten the query, I've basically ended up again with a mixed query.
Even though I am showing in the SQL query above that I am filtering by year, in fact I need to be able to determine the current balance from any day.
private LedgerBalanceDto GetAccountBalance(BaseAccountCode account, DateTime periodFrom, DateTime periodTo, string queryName)
{
using (var session = MvcApplication.RavenSession)
{
var query = session.Query<Transactions_ByDailyBalance.Result, Transactions_ByDailyBalance>()
.Where(c=>c.AccountId==account.Id && c.Date>=periodFrom && c.Date<=periodTo)
.OrderBy(c=>c.Date)
.ToList();
var debits = query.Sum(c => c.Debit);
var credits = query.Sum(c => c.Credit);
var ledgerBalanceDto = new LedgerBalanceDto
{
Account = account,
Credits = credits,
Debits = debits,
Currency = account.Currency,
CurrencySymbol = account.CurrencySymbol,
Name = queryName,
PeriodFrom = periodFrom,
PeriodTo = periodTo
};
return ledgerBalanceDto;
}
}
Required result:
GroupCompanyId AccountCurrency AccountName Year OpeningDebits OpeningCredits Db Cr
Groupcompanies-2 EUR Customer 1 2011 148584.2393 125869.91 10297.6891 28023.98
Groupcompanies-2 EUR Customer 2 2011 236818.0054 233671.55 50959.85 54323.38
Groupcompanies-2 USD Customer 3 2011 69426.11761 23516.3776 10626.75 0
Groupcompanies-2 USD Customer 4 2011 530587.9223 474960.51 97463.544 131497.16
Groupcompanies-2 USD Customer 5 2011 29542.391 28850.19 4023.688 4231.388
Any suggestions would be greatly appreciated
Jeremy
In answer to the comment
I basically ended up doing pretty much the same thing. Actually, I wrote an index that does it in only two hits - once for the opening balance and again for the period balance. This is almost instantaneous for grouping by the account name, category etc.
However my problem now is getting a daily running balance for the individual account. If I bring down all the data for the account and the period, its not a problem - I can sum the balance on the client, however, when the data is paged, and the debits and credits are grouped by Date and Id, the paging cuts across the date, so the opening/closing balance is not correct.
Page 1
Opening balance until 26/7/12 = 0
25/7/12 Acct1 Db 100 Cr 0 Bal +100 Runn Bal +100
26/7/12 Acct1 Db 100 Cr 0 Bal +100 Runn Bal +200
26/7/12 Acct1 Db 200 Cr 0 Bal +200 Runn Bal +400
Closing balance until 26/7/12 = +400
Page 2
Opening balance until 26/7/12 = +450 (this is wrong - it should be the balance at the end of Page 1, but it is the balance until the 26/7/12 - i.e. includes the first item on Page 2)
26/7/12 Acct1 Db 50 Cr 0 Bal +50 Runn Bal +500 (should be +450)
27/7/12 Acct1 Db 60 Cr 0 Bal +60 Runn Bal +560 (should be +510)
I just can't think up an algorithm to handle this.
Any ideas?
Hi this is a problem I have also faced recently with RavenDb when I needed to retrieve rolling balances as at any imaginable date. I never found a way of doing this all in one go but I managed reduce the amount of documents that I needed to pull back in order to calculate the rolling balance.
I did this by writing multiple map reduce indexes that summed up the value of transactions within specific periods:
My First Summed up the value of all transactions grouped at the year level
My Second index Summed up the value of all transactions at the Day level
So if someone wanted their account balance As At 1st June 2012 I would:
Use the Year level Map-reduce index to get the Value of transactions for years up to 2012 and summed them together (so if transactions started being captured in 2009 I should be pulling back 3 documents)
Use the Day level Map-reduce index to get all documents from the start of the year and the 1st of June
I then Added the Day totals to the year totals for my final rolling balance (I could have also had a monthly map reduce as well but didn't bother).
Anyway not as quick as in SQL but it was the best alternative I could come up with to avoid bringing back every single transaction