I have this query that calculates the expected value of a receipt, based on the 'channel' of acquisition of the user, on the 'id_store' and on the 'country' of the user.
The resulting query has this columns.
Count | id_store | country | price_usd | channel | T2S | ExpectedRevenue | ExpectedRevenue_projections
(note: ExpectedRevenue = count * price_usd * T2S)
In this query I want to know the value of those receipts that where purchased on August and expire on September (these products have a trial period, and we calculate their value is based on the historical conversion rate (Trial 2 subscription a.k.a. T2S)).
The problem arises when we do not have historical data for some scenarios; either we started selling different with id_stores, new country, channel, or any combination of the previous ones and the T2S becomes as a 'null' value and column 'ExpectedRevenue' therefore has 'null' values' ---> That is why I have a 'CASE' function that makes T2S to take the value of '.28' whenever this happens and I only have to sum the column 'ExpectedRevenue_projections' in order to get the final result.
However, this '.28' is just a fixed value that is not accurate at all (we have products from 10 to 120$...).
That's why I'm asking dear stackoverflow contributors is to replace this '28%' for another T2S that in this case would be calculated historically according to 'country' and 'price_usd' intervals such as (0-15), (15.01-29.99), (30 - 49.99)... and so on.
(The reason to put intervals is that 'price_usd' is calculated based on the exchange rate at the moment of the creation so the same product purchase by a customer in foreign currency could be 49.99, 49.98 , 49.97... and T2S would come as 'null' if there is not historical data).
Thank you
SELECT
r.count AS count,
r.id_store AS id_store,
r.country AS country,
r.price_usd AS price_usd,
r.channel AS channel,
a.count / (a.count + u.count) AS T2S,
r.count * r.price_usd * (a.count / (a.count + u.count)) AS ExpectedRevenue,
CASE WHEN (a.count / (a.count + u.count)) is null then (r.count * r.price_usd * .28) else r.count * r.price_usd * (a.count / (a.count + u.count)) END AS ExpectedRevenue_projections
FROM
(
select count(distinct(r.user_id)) AS count, p.id_store, u.country, r.price_usd, channel
from receipts as r
inner join products as p on p.id=r.product_id
inner join customers as c on r.customer_id=c.id
inner join users as u on u.id=r.user_id
where
MONTH(DATE_ADD(DATE_ADD(r.original_subscription_at, INTERVAL p.trial_days DAY), INTERVAL p.trial_months MONTH)) = 9
and YEAR(original_subscription_at) = 2017
and MONTH(original_subscription_at) = 8
and YEAR(r.expiration_at) = 2017
and MONTH(r.expiration_at) = 9
and r.status='trial'
and p.platform not in ('manual')
and c.tester=0
group by 2,3,4,5
) AS r
LEFT JOIN
(
select count(distinct r.user_id) AS count, u.country, p.id_store, channel
from receipts as r
inner join products as p on p.id=r.product_id
inner join users as u on u.id=r.user_id
where year(r.created_at)=2017
AND r.status = 'active'
group by 2,3,4
) AS a
ON r.country = a.country AND r.id_store = a.id_store AND r.channel = a.channel
LEFT JOIN
(
select count(distinct r.user_id) AS count, u.country, p.id_store, channel
from receipts as r
inner join products as p on p.id=r.product_id
inner join users as u on u.id=r.user_id
where year(r.created_at)=2017
AND r.status = 'unpaid'
group by 2,3,4
) AS u
ON r.country = u.country AND r.id_store = u.id_store AND r.channel = u.channel
I am trying to add the tax and multiply the result with a total price.
Here are the tables
"Charge" Table
Charge_Type
Tax_type
charge type tax list
I want to calculate the tax and the multiply with the amount for each charge_id
I tried attempting this way:
SELECT `charge_id` AS "Charge ID", SUM( tt.percentage ) AS "Tax"
FROM charge c, charge_type ct, tax_type tt, charge_type_tax_list cttl
WHERE tt.tax_type_id = cttl.tax_type_id
GROUP BY c.charge_type_id, c.charge_id
LIMIT 0 , 30
You are using a join syntax that was made redundant more than twenty years ago. Whichever book or class or tutorial has been teaching you this outdated syntax, quit it. This syntax is prone to errors, as your own query plainly shows. Your query translated to proper joins is:
SELECT `charge_id` AS "Charge ID", SUM( tt.percentage ) AS "Tax"
FROM charge c
CROSS JOIN charge_type ct
CROSS JOIN tax_type tt
INNER JOIN charge_type_tax_list cttl ON tt.tax_type_id = cttl.tax_type_id
GROUP BY c.charge_type_id, c.charge_id
LIMIT 0 , 30
You are combining all charge records with all charge_type records and all tax_type records. 6 x 3 x 3 = 54 records in your example. This makes no sense. You would want to join only related records in the first place.
What you really want to do is join charges with their tax sum:
select
c.charge_id,
tax.tax_sum,
c.amount,
c.amount * (1 + coalesce(tax.tax_sum, 0)) as taxed_amount
from charge c
left join
(
select
cttl.charge_type_id,
sum(tt.percentage) as tax_sum
from charge_type_tax_list cttl
join tax_type tt on tt.tax_type_id = cttl.tax_type_id
group by cttl.charge_type_id
) tax on tax.charge_type_id = c.charge_type_id;
You could do an INNER JOIN between the tables and calculate the corresponding percentage's grouped by charge id. The query below should do the trick:
SELECT charge.charge_type_id, (SUM(percentage) + 1) * charge.amount AS total_tax
FROM charge INNER JOIN charge_type ON charge.charge_type_id = charge_type.charge_type_id
INNER JOIN charge_type_tax_list ON charge_type.id = charge_type_tax_list.charge_type_id
INNER JOIN tax_type ON charge_type_tax_list.tax_type_id = tax_type.tax_type_id GROUP BY charges.id;
select
a.ClientID,
f.Currency,
a.OrganizationName,
COALESCE(sum(b.GrandTotal),0) as SaleGrandTotal,
COALESCE(sum(g.AmountReceived),0) as AmountReceived,
COALESCE(sum(b.GrandTotal - g.AmountReceived),0) as SaleBalanceRemaining,
COALESCE(sum(d.GrandTotal), 0) as PurchaseGrandTotal,
COALESCE(sum(e.AmountPaid), 0) as AmountPaid,
COALESCE(sum(d.GrandTotal - e.AmountPaid),0) as PurchaseBalanceRemaining,
COALESCE(sum(b.GrandTotal - g.AmountReceived),0) - COALESCE(sum(d.GrandTotal - e.AmountPaid),0) as Total
from na_clients as a
join na_currency as f
left join na_transaction as b
on a.ClientID = b.ClientID and b.CurrencyID = f.CurrencyID and b.IsActive = 1
left join na_recoverylogs as g
on b.TID = g.TID
left join na_purchase as d
on a.ClientID = d.ClientID and d.CurrencyID = f.CurrencyID and d.IsActive = 1
left join na_purchaselogs as e
on e.PID = d.PID
group by a.OrganizationName,f.Currency
order by a.OrganizationName
I am using multiple currency like dollar,CNY,rupees.
It was working fine but today i noticed sum() double value like b.GrandTotal should be 11500 but its return 23000
Table Client:
clientid,name,organizationName
1,client1,OrgName
2,client2,OrgName
Table Currency:
currencyid,cname
1,Dollar
2,Rupees
Table Transaction:
tid,clientid,currencyid,grandTotal,amountReceived,balanceremaining
1,1,1,11000,0,11000
2,1,1,500,0,500
Table recoveryLogs: // Another Error Here
id,tid,amountreceived
1,1,0
2,2,0
3,2,2000 // Again sum() multiply value - because of PID 2 is repeating
Table Purchase:
pid,clientid,currencyid,grandTotal,amountPaid,balanceRemaining
1,1,1,25000,0,25000
1,2,2,2,3000,1000,2000
Now I am using sum(b.grandTotal) instead of 11500 it return 23000
Table PurchaseLogs: // Another Error Here
id,pid,amountpaid
1,1,0
2,2,1000
3,1,1000 // Again sum() multiply value - because of PID 1 is repeating
So result should be:
Client: Client1
SaleGrandTotal: 11500
AmountReceived: 0
SaleBalanceRemaining: 11500
PurchaseGrandTotal: 25000
AmountPaid: 0
PurchaseBalanceRemaining: 25000
Total Amount: -13500
But result i get:
Client: Client1
SaleGrandTotal: 23000
AmountReceived: 0
SaleBalanceRemaining: 23000
PurchaseGrandTotal: 50000
AmountPaid: 0
PurchaseBalanceRemaining: 50000
Total Amount: -27000
If i remove purchase clause(d and e) or transaction(b and g) clause from query it's working fine individually.
The reason data is doubling is your ClientID has different occurrences in Transaction and Purchase tables and hence not a 1-to-1 match. ClientID = 1 and CurrencyID = 1 appears twice in Transaction and only once in Purchase. When you join the tables, a combination set of 1 x 2 = 2 ClientID records result with some fields repeating data. Thus, summing will double for repeat entries. As illustration:
Transaction Data | Purchase Data
row1: 1,1,1,11000,0,11000 | 1,1,1,25000,0,25000
row2: 2,1,1,500,0,500 | 1,1,1,25000,0,25000
Consider separating the aggregation between both tables using derived tables. Then, join the four underlying aggregates (transaction, purchase, recovery log, purchase log) for final query. The join will match 1-to-1 if you aggregate, grouping on ClientID and CurrencyID, TID and PID.
SELECT
transAgg.ClientID, transAgg.Currency, transAgg.OrganizationName,
transAgg.SaleGrandTotal, recovLogAgg.SumOfAmtReceived,
(transAgg.SaleGrandTotal - recovLogAgg.SumOfAmtReceived) as SaleBalanceRemaining,
purchAgg.PurchaseGrandTotal, purchLogAgg.SumOfAmtPaid,
(purchAgg.PurchaseGrandTotal - purchLogAgg.SumOfAmtPaid) as PurchaseBalanceRemaining,
((transAgg.SaleGrandTotal - recovLogAgg.SumOfAmtReceived) -
(purchAgg.PurchaseGrandTotal - purchLogAgg.SumOfAmtPaid)) As [Total]
FROM
(SELECT
a.ClientID, f.CurrencyID, f.Currency, a.OrganizationName,
COALESCE(sum(b.GrandTotal),0) as SaleGrandTotal
FROM na_clients as a
INNER JOIN na_currency as f
LEFT JOIN na_transaction as b
ON a.ClientID = b.ClientID
AND b.CurrencyID = f.CurrencyID
AND b.IsActive = 1
GROUP BY a.ClientID, a.OrganizationName, f.CurrencyID, f.Currency
ORDER BY a.OrganizationName) As transAgg
INNER JOIN
(SELECT
a.ClientID, f.CurrencyID, f.Currency, a.OrganizationName,
COALESCE(sum(d.GrandTotal), 0) as PurchaseGrandTotal
FROM na_clients as a
INNER JOIN na_currency as f
LEFT JOIN na_purchase as d
ON a.ClientID = d.ClientID
AND d.CurrencyID = f.CurrencyID
AND d.IsActive = 1
GROUP BY a.ClientID, a.OrganizationName, f.CurrencyID, f.Currency
ORDER BY a.OrganizationName) As purchAgg
ON transAgg.ClientID = purchAgg.ClientID
AND transAgg.CurrencyID = purchAgg.CurrencyID
INNER JOIN
(SELECT
g.TID, COALESCE(sum(g.AmountReceived),0) As SumOfAmtReceived
FROM na_recoverylogs as g
GROUP BY g.TID) As recovlogAgg
ON transAgg.TID = recovlogAgg.TID
INNER JOIN
(SELECT
e.PID, COALESCE(sum(e.AmountPaid),0) As SumOfAmtPaid
FROM na_purchaselogs as e
GROUP BY e.PID) As purchlogAgg
ON purchAgg.PID = purchlogAgg.PID
Let me know how to write select query in case statement.
select
ROW_NUMBER() OVER(Order by vendor.VendorName ) AS ID,
PH.PurchasingHeaderID as BILLNo,
PH.TotalPriceCompanyCurrency as Balance,
acc.AccountName as [Account_Name]
**Into #tempOpenVedorlist**
from PurchasingHeader PH
LEFT OUTER JOIN TransactionType Trans ON PH.TransactionTypeID =Trans.TransactionTypeID
LEFT OUTER JOIN Vendor vendor on PH.VendorID=vendor.VendorID
LEFT OUTER JOIN PaymentTerm PT on PT.PaymentTermID = vendor.PaymentTermID
LEFT OUTER JOIN PurchasingDetail PD on PD.PurchasingHeaderID = PH.PurchasingHeaderI
LEFT OUTER JOIN Account Acc on Acc.AccountID= PD.FinancialAccountID
where PH.TransactionTypeID=7
Group by vendor.VendorName,
PH.PurchasingHeaderID,PH.TotalPriceCompanyCurrency,acc.AccountName
I GOT THIS RESULT :
with this result: Here i have No : VB1003 two times but Account Name is different.
ID BILLNo Account_Name Balance
-------------------------------------------------------------
101 VB1000 Cash-Petty Cash 4000.00
102 VB1001 Accounts Receivable 5000.00
103 VB1003 Cash-PettyCash 6000.00
104 VB1003 Cash 6000.00
105 VB1004 UndepositedFunds 7000.00
Here i have to show ;
I need this result :
ID BILLNo Account_Name Balance
------------------------------------------------------
101 VB1000 Cash-PettyCash 4000.00
102 VB1001 AccountsReceivable 5000.00
103 VB1003 ---Multiple---- 6000.00
104 VB1004 UndepositedFunds 7000.00
For aboue result what i have did : i have taken all the data in temp table.
Am able show Multiple string for which has more than one No.
But unfortunatly am not able show Account Name for which has only one BILLNo.
select ROW_NUMBER() OVER(Order by BILLNo ) AS ID,
[BILLNo],
Balance,
CASE
WHEN count(BILLNo)>1 THEN 'Multipul'
WHEN count(BILLNo)<2 THEN **(Select Account_Name from #tempOpenVedorlist )**
End As [Financial_Account]
from #tempOpenVedorlist
Group By BILLNo,Balance
Let me know how can i get account name from temp table which is related to that BILLNo.
Remove the AccountName from the GROUP BY and put an aggregate on that.
SELECT ROW_NUMBER() OVER(Order by vendor.VendorName ) AS ID,
PH.PurchasingHeaderID as BILLNo,
PH.TotalPriceCompanyCurrency as Balance,
CASE WHEN MIN(acc.AccountName) IS NULL
THEN '----'
WHEN MIN(acc.AccountName) = MAX(acc.AccountName)
THEN MIN(acc.AccountName)
ELSE '--MULTIPLE--'
END as [Account_Name]
INTO #tempOpenVedorlist
FROM PurchasingHeader PH
LEFT OUTER JOIN TransactionType Trans
ON PH.TransactionTypeID =Trans.TransactionTypeID
LEFT OUTER JOIN Vendor vendor
ON PH.VendorID=vendor.VendorID
LEFT OUTER JOIN PaymentTerm PT
ON PT.PaymentTermID = vendor.PaymentTermID
LEFT OUTER JOIN PurchasingDetail PD
ON PD.PurchasingHeaderID = PH.PurchasingHeaderI
LEFT OUTER JOIN Account Acc
ON Acc.AccountID= PD.FinancialAccountID
WHERE PH.TransactionTypeID=7
GROUP BY vendor.VendorName,
PH.PurchasingHeaderID,
PH.TotalPriceCompanyCurrency
SELECT (select count(u.ag_code)
from table1 as u inner join table2 as tc
on u.industry_id=tc.tempcatid
where u.ag_code!=0) as agnt,
(select count(u.ag_code)
from table1 as u inner join table2 as tc
on u.industry_id=tc.tempcatid where u.ag_code=0),as dircus,
tc.catename from table1 as u inner join table2 as tc
where u.industry_id=tc.tempcatid
group by tc.tempcatid
this query have error
i need two count and category name in one query
this is the condition for count
ag_code!=0
ag_code=0
in table1 have column ag_code (this have 0 and nonzero value)
my result need like this
Full Texts
agent customer catename
11 3 Real Estate
15 1 Automobile
3 0 Medical
34 77 Business
1 45 Travel & Hotels
11 3 Construction & Engineering
SELECT tc.catename,
count(case when u.ag_code!=0 then 1 end) agnt,
count(case when u.ag_code =0 then 1 end) dircus
from table1 as u
inner join table2 as tc on u.industry_id=tc.tempcatid
group by tc.tempcatid, tc.catename
Hi There you might be able to use the below example to get back the result you require.
Select SUM(Inactive) Inactive ,SUM(Active) Active FROM
(
Select Count(t1.UserId) Inactive,0 Active
FROM
(select * from users where inactive=1) as t1
UNION
SELECT 0 Inactive,Count(t2.UserId) Active FROM
(select * from users where inactive=0) as t2
) as result