Count Total Transaction each specific row even if 0 - mysql

I have a 3 Columns namely:
Payment Channel
Payment Name
Total Transaction
The Total Transaction will be the COUNT of each Payment Channel and Payment Name.
In the Payment Channel, values have PC01-PC09.
I want my result to display all the Payment Channel even if no transactions.
Here is my SQL Script:
SELECT
B2C_BUY_LOG.PG_CHANNEL AS Payment_Channel,
COMM_CODE.CODE_NAME AS Payment_Name,
COUNT(B2C_BUY_LOG.PAY_ID) AS Total_Transaction
FROM B2C_BUY_LOG
INNER JOIN B2C_BUY_HIST ON B2C_BUY_LOG.PAY_ID = B2C_BUY_HIST.PAY_ID
INNER JOIN COMM_CODE ON B2C_BUY_LOG.PG_CHANNEL = COMM_CODE.CODE
WHERE B2C_BUY_LOG.RET_CODE = 1
AND B2C_BUY_LOG.PAY_ID LIKE '190220%'
AND COMM_CODE.CODE IN('PC01', 'PC02', 'PC03', 'PC04', 'PC05', 'PC06', 'PC07', 'PC08', 'PC09')
GROUP BY Payment_Channel, Payment_Name;
Here is the result of my Query:
Payment_Channel Payment_Name Total_Transaction
PC01 Name-1 14
PC02 Name-2 2
PC03 Name-3 7
PC04 Name-4 9
PC06 Name-6 21
PC08 Name-8 18
PC09 Name-9 95
This query returns only the match values between the joined tables because it is INNER JOIN and the PC05 and PC07 is missing on the result because it has no transaction. I also tried different JOINS.
How can I display the PC05 and PC07 with a count of 0 if no transaction?
Thanks!

You can try below, Issue is with column on which filter is applied.
SELECT
B2C_BUY_LOG.PG_CHANNEL AS Payment_Channel,
COMM_CODE.CODE_NAME AS Payment_Name,
COUNT(B2C_BUY_LOG.PAY_ID) AS Total_Transaction
FROM B2C_BUY_LOG
left outer JOIN B2C_BUY_HIST ON B2C_BUY_LOG.PAY_ID = B2C_BUY_HIST.PAY_ID
left outer INNER JOIN COMM_CODE ON B2C_BUY_LOG.PG_CHANNEL = COMM_CODE.CODE
WHERE B2C_BUY_LOG.RET_CODE = 1
AND B2C_BUY_LOG.PAY_ID LIKE '190220%'
AND B2C_BUY_LOG.CODE IN('PC01', 'PC02', 'PC03', 'PC04', 'PC05', 'PC06', 'PC07', 'PC08', 'PC09')
GROUP BY Payment_Channel, Payment_Name;

Use left join and move your other condition in ON Clause like below-
SELECT
B2C_BUY_LOG.PG_CHANNEL AS Payment_Channel,
COMM_CODE.CODE_NAME AS Payment_Name,
COUNT(B2C_BUY_LOG.PAY_ID) AS Total_Transaction
FROM B2C_BUY_LOG
left JOIN B2C_BUY_HIST ON B2C_BUY_LOG.PAY_ID = B2C_BUY_HIST.PAY_ID and B2C_BUY_LOG.RET_CODE = 1 AND B2C_BUY_LOG.PAY_ID LIKE '190220%'
left JOIN COMM_CODE ON B2C_BUY_LOG.PG_CHANNEL = COMM_CODE.CODE
and COMM_CODE.CODE IN('PC01', 'PC02', 'PC03', 'PC04', 'PC05', 'PC06', 'PC07', 'PC08', 'PC09')
GROUP BY Payment_Channel, Payment_Name;

Related

Sql Query with 1 Join and 2 Where Clauses not returning all records

So guys, trying to write a query to get the count of statuses where project_id = ? and statuses in 'New' from a couple of tables so let me break it down.
I have these three tables
Case_Status
id case_status
1 New
2 Failed
3. Accepted
Referral
id case_status_id project_id application_id
1 1 1 20
2 2 1 21
Project
id name
1 project1
2 project2
So this is my query
SELECT COUNT(referrals.id) AS count_all, case_statuses.case_status AS counted
FROM "case_statuses" LEFT OUTER JOIN "referrals" ON "referrals"."case_status_id" = "case_statuses"."id"
WHERE "case_statuses"."deleted_at" IS NULL AND (case_statuses.case_status IN ('New') AND referrals.project_id = 1)
GROUP BY case_statuses.case_status;
This is my result
count_all counted
1 New
1 Failed
But I am expecting this result instead
count_all counted
1 New
1 Failed
0 Accepted
Does anyone know what's wrong with my query that isnt showing count for all the case_statuses?
Thanks
Conditions on the second table (in a left join) should be in the on clause:
SELECT COUNT(r.id) AS count_all, cs.case_status AS counted
FROM case_statuses cs LEFT OUTER JOIN
referrals r
ON r.case_status_id = cs.id AND r.project_id = 1
WHERE cs.deleted_at IS NULL AND cs.case_status NOT IN ('New')
GROUP BY cs.case_status;
Otherwise, the WHERE clause turns the outer join into an inner join.
change your query like this
SELECT COUNT(referrals.id) AS count_all, case_statuses.case_status AS counted
FROM "case_statuses" LEFT JOIN "referrals" ON "referrals"."case_status_id" = "case_statuses"."id" AND referrals.project_id = 1
WHERE "case_statuses"."deleted_at" IS NULL AND case_statuses.case_status NOT IN ('New')
GROUP BY case_statuses.case_status;
Given your data and the expected result you just need to loose the WHERE clause.
SELECT COUNT(referrals.id) AS count_all, case_statuses.case_status AS counted
FROM case_statuses
LEFT OUTER JOIN referrals ON referrals.case_status_id = case_statuses.id
GROUP BY case_statuses.case_status;
See this fiddle for details.

mysql sum() return double value using multiple joins

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

SQL Joining 2 tables: 1 `ON` vs 2 `ON`

I have a query like:
select gift.id as giftId, gift.title, count(vouchercode.id) as stock, vouchertemplate.unlimited, gift.voucherTemplate, vouchertemplate.id as voucherId,vouchertemplate.title
from gift
inner join vouchertemplate
left join vouchercode
on gift.voucherTemplate = vouchertemplate.id
on vouchertemplate.id = vouchercode.template
and vouchercode.given = 0
where gift.id in (13,14,15,16)
I find that this does not give me the correct result. It appears on gift.voucherTemplate = vouchertemplate.id does not work as expected. I need it before the left join. So I cannot just put all the join conditions together? I specified the table names and columns to join, so I wonder why the difference?
The below query gives me the correct result.
select gift.id as giftId, gift.title, count(vouchercode.id) as stock, vouchertemplate.unlimited, gift.voucherTemplate, vouchertemplate.id as voucherId,vouchertemplate.title
from gift
inner join vouchertemplate
on gift.voucherTemplate = vouchertemplate.id <<< DIFF HERE
left join vouchercode
on vouchertemplate.id = vouchercode.template
and vouchercode.given = 0
where gift.id in (13,14,15,16)
It doesnt work that way. You need to have condition for each join. you need to specify on which column (or conidtion) your two tables should be joined.

Select distinct totals from access tables

I have three tables: T_O, T_C, & T_D they each have a date (run_date) and count column.
I need to select the data to show a summary by date for each count. I cannot get the nested sql to make it look right.
Needs to be grouped by Run Date. End result should look like this:
Run_Date Total Defects Not Closed Closed
05/29/13 178 100 78
06/04/13 204 103 101
06/11/13 234 114 120
I assume the three tables each have two columns: Run_Date and Total Defects, Not Closed or Closed. If you have a table with all the run dates in it, something like this will work:
SELECT
RunDates.Run_Date,
T_D.[Total Defects],
T_O.[Not Closed],
T_C.[Closed]
FROM ((
RunDates
LEFT JOIN T_C ON RunDates.Run_Date = T_C.Run_Date)
LEFT JOIN T_O ON RunDates.Run_Date = T_O.Run_Date)
LEFT JOIN T_D ON RunDates.Run_Date = T_D.Run_Date
If not, you will need to construct one using a UNION (not UNION ALL):
SELECT
RunDates.Run_Date,
T_D.[Total Defects],
T_O.[Not Closed],
T_C.[Closed]
FROM ((
(SELECT Run_Date FROM T_C
UNION
SELECT Run_Date FROM T_O
UNION SELECT Run_Date FROM T_D) AS RunDates
LEFT JOIN T_C ON RunDates.Run_Date = T_C.Run_Date)
LEFT JOIN T_O ON RunDates.Run_Date = T_O.Run_Date)
LEFT JOIN T_D ON RunDates.Run_Date = T_D.Run_Date

sql query implement two count in one

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