I'd like to group by state and sum up the total pledge amount, but if the pledge status is equal to canceled sum up the total paid. I'm not sure the best way to do this?
Thank you for feedback and help!
SELECT
dbo.FoundationCompanies.companyState,
CASE WHEN dbo.FondationOrder.pledgeStatus = 'canceled' THEN
(
SELECT SUM(paid) AS total
FROM dbo.FoundationInvoice
WHERE (orderId = dbo.FondationOrder.orderId)
)
ELSE
dbo.FondationOrder.pledgeAmount
END AS pledgeAmount
FROM
dbo.FoundationCompanies
INNER JOIN
dbo.FondationOrder
ON
dbo.FoundationCompanies.compId = dbo.FondationOrder.compId
GROUP BY dbo.FoundationCompanies.companyState
ORDER BY dbo.FoundationCompanies.companyState
Example data:
Algonquin 2500.00
Atlanta 500000.00
Batesville 10000.00
Batesville 25000.00
I would like the results to return as:
Amount |State
$100,000.00|AL
$145,000.00|AZ
Q : I'm not sure the best way to do this?
A : no,it'll use multi slow query ,you can use left join subquery to avoid it,like below script :
SELECT
companyState,
CASE WHEN FondationOrder.pledgeStatus = 'canceled' THEN
T.total
ELSE
FondationOrder.pledgeAmount
END AS pledgeAmount
FROM FoundationCompanies
INNER JOIN FoundationContacts ON FoundationCompanies.companyId = FoundationContacts.companyId
INNER JOIN FondationOrder ON FoundationContacts.contactId = FondationOrder.contactId
LEFT JOIN (
SELECT orderId,SUM(paid) AS total
FROM FoundationInvoice
GROUP BY orderId
) T on T.orderId = FondationOrder.orderId
GROUP BY FoundationCompanies.companyState
ORDER BY FoundationCompanies.companyState
Add Order table to your join then use the aggregate function :
SELECT
dbo.FoundationCompanies.companyState,
SUM(IIF(dbo.FondationOrder.pledgeStatus = 'canceled', dbo.FoundationInvoice.paid, dbo.FondationOrder.pledgeAmount)) AS pledgeAmount
FROM dbo.FoundationCompanies
INNER JOIN dbo.FoundationContacts ON dbo.FoundationCompanies.companyId = dbo.FoundationContacts.companyId
INNER JOIN dbo.FondationOrder ON dbo.FoundationContacts.contactId = dbo.FondationOrder.contactId
LEFT JOIN dbo.FoundationInvoice ON dbo.FondationOrder.orderId = dbo.FoundationInvoice.orderId
GROUP BY dbo.FoundationCompanies.companyState
Related
This my code and I want a output like in the picture:
SELECT `test`.custinfo.CustID, OtherDeductionName AS DeductionName, sum(OtherDeductionAmount) as DeductionAmount FROM `db_payroll`.`tbl_otherdeductions`
LEFT JOIN `db_payroll`.tbl_payroll
ON `db_payroll`.tbl_payroll.OtherDeductionsID = `db_payroll`.tbl_otherdeductions.OtherDeductionsID
LEFT JOIN `test`.tbl_testpayinternal on tbl_testpayinternal.PRID = tbl_payroll.PRID
LEFT JOIN `test`.tbl_testpay on tbl_testpay.PRID = tbl_payroll.PRID
LEFT JOIN `test`.custinfo on(CASE WHEN tbl_payroll.EmpID LIKE '%EX%' THEN `test`.custinfo.custid = `test`.tbl_testpay.custid ELSE `test`.custinfo.custid = `test`.tbl_testpayinternal.custid END)
WHERE `tbl_payroll`.`status` = 'Done' and `test`.custinfo.CustID = '00000008' and `db_payroll`.`tbl_payroll`.date_start = '2022-11-14' and `db_payroll`.`tbl_payroll`.date_end = '2022-11-28'
AND `db_payroll`.`tbl_payroll`.OtherDeductionsID <> ''
GROUP BY DeductionName
UNION
SELECT `test`.custinfo.CustID, StatutoryDeductionsName AS DeductionName, sum(StatutoryEE) as DeductionAmount FROM `test`.`tbl_statutorydeductions`
LEFT JOIN `test`.tbl_statutorydeductionstype
ON `test`.tbl_statutorydeductions.StatutoryDeductionsTypeID = `test`.tbl_statutorydeductionstype.StatutoryDeductionsTypeID
LEFT JOIN `db_payroll`.tbl_payroll
ON `db_payroll`.tbl_payroll.StatutoryDeductionsID = `test`.tbl_statutorydeductions.StatutoryDeductionsID
LEFT JOIN `test`.tbl_testpayinternal on tbl_testpayinternal.PRID = tbl_payroll.PRID
LEFT JOIN `test`.tbl_testpay on tbl_testpay.PRID = tbl_payroll.PRID
LEFT JOIN `test`.custinfo on(CASE WHEN tbl_payroll.EmpID LIKE '%EX%' THEN `test`.custinfo.custid = `test`.tbl_testpay.custid ELSE `test`.custinfo.custid = `test`.tbl_testpayinternal.custid END)
WHERE `tbl_payroll`.`status` = 'Done' and `test`.custinfo.CustID = '00000008' and `db_payroll`.`tbl_payroll`.date_start = '2022-11-14' and `db_payroll`.`tbl_payroll`.date_end = '2022-11-28'
AND `db_payroll`.`tbl_payroll`.StatutoryDeductionsID <> ''
GROUP BY DeductionName
UNION
SELECT `test`.custinfo.CustID, TypeOfLoan AS DeductionName, sum(AmortAmount) as DeductionAmount FROM `test`.`tbl_benamortloan`
LEFT JOIN `db_payroll`.tbl_payroll
ON `test`.tbl_benamortloan.IDno = `db_payroll`.tbl_payroll.EmpID AND `test`.tbl_benamortloan.CutOffID = `db_payroll`.tbl_payroll.CutOffID
LEFT JOIN `test`.tbl_testpayinternal on tbl_testpayinternal.PRID = tbl_payroll.PRID
LEFT JOIN `test`.tbl_testpay on tbl_testpay.PRID = tbl_payroll.PRID
LEFT JOIN `test`.custinfo on(CASE WHEN tbl_payroll.EmpID LIKE '%EX%' THEN `test`.custinfo.custid = `test`.tbl_testpay.custid ELSE `test`.custinfo.custid = `test`.tbl_testpayinternal.custid END)
WHERE `tbl_payroll`.`status` = 'Done' and `test`.custinfo.CustID = '00000008' and `db_payroll`.`tbl_payroll`.date_start = '2022-11-14' and `db_payroll`.`tbl_payroll`.date_end = '2022-11-28'
AND `db_payroll`.`tbl_payroll`.LoanPaymentsID <> ''
GROUP BY DeductionName
ORDER BY DeductionName
This is the output I want
Can you help me with this
Well, what I see so far is a great big UNION query which will produce three concatenated groups of data, each one containing sums. So maybe now all you need to do is something like:
SELECT SUM(DeductionAmount) FROM
(
..insert the text of your present query here..
)
Of course, this is the simplest example.
The key idea is this: "your present query" – textually included, within parentheses – is used as a subquery of a primary query that calculates the sum of all of the DeductionAmount columns now being provided by "your present query." "Your present query" is the source of the rows seen by the outer-level one, and what you finally get is "the result of the outer-level one."
(Always separately review the result of your intended subquery, to be sure that it is consistent and correct, before wrapping it into an outer-level query. "Query bugs" can be hard to diagnose otherwise.)
I have put down below a query to retrieve from four tables which are
Sales_Invoice, New_Customer, Company_Information, Expense
Query:
select
isnull(sum(Expense.Expense_Amount), 0.00), as ExpenseAmount,
Company_Information.Company_Name,
Sales_Invoice.Invoice_No, Sales_Invoice.Invoice_Date, Sales_Invoice.Item_Name,
New_Customer.Customer_Name, New_Customer.Customer_ID
from
Sales_invoice, Company_Information, New_Customer, Expense
where
Sales_Invoice.Customer_Id = New_Customer.Customer_ID
and Sales_Invoice.Invoice_No = Expense.Invoice_No
group by
Company_Information.Company_Name,
Sales_Invoice.Invoice_No, Sales_Invoice.Invoice_Date, Sales_Invoice.Customer_ID,
Sales_Invoice.Item_Name, New_Customer.Customer_Name, New_Customer.Customer_ID
The query is working well but if the Expense table has no values Expense.Invoice_No does not match with Sales_Invoice.Invoice_No, then the query above will return empty rows.
But what I wish to do is that, if Expense.Invoice_No does not exists then I still want to have my rows provided that expense amount return 0.00
Use standard joins! Then, you can easily handle "missing" relations with a left join.
Your question suggests:
select
coalesce(sum(e.expense_amount), 0.00) as expenseamount,
ci.company_name,
si.invoice_no, si.invoice_date, si.item_name,
nc.customer_name, nc.customer_id
from new_customer nc
inner join company_information ci on ???
inner join sales_invoice si on si.customer_id = nc.customer_id
left join expense e on e.invoice_no = si.invoice_no
group by
ci.company_name,
si.invoice_no, si.invoice_date, si.customer_id,
si.item_name, nc.customer_name, nc.customer_id
Note that you original code seems to me missing a join condition between the customers and companies. I represented it as ??? in the query.
You could also express the same logic with a correlated subquery, which would avoid outer aggregation:
select
(
select coalesce(sum(e.expense_amount), 0.00)
from expense e
where e.invoice_no = si.invoice_no
) as expenseamount,
ci.company_name,
si.invoice_no, si.invoice_date, si.item_name,
nc.customer_name, nc.customer_id
from new_customer nc
inner join company_information ci on ???
inner join sales_invoice si on si.customer_id = nc.customer_id
SQL Query taking too much time to execute. Working fine at UAT. I need to compare data of two tables and want to get difference. Below mention is my query.
Select *
from tblBrandDetailUsers tbdu
inner join tblBrands tbs on tbs.BrandId = tbdu.BrandId
left join tblBrandDetails tbd on tbd.CategoryId = tbdu.CategoryId
and tbd.BrandId = tbdu.BrandId
and tbd.CityId = tbdu.CityId
inner join tblCategory tc on tbdu.CategoryId = tc.CategoryId
inner join tblCity tcc on tcc.CityId = tbdu.CityId
where isnull(tbdu.SaleAmount,-1) <> isnull(tbd.SaleAmount,-1)
and isnull(tbdu.CityId,0) = 3
and isnull(tbdu.TopLevelCategoryId,0) = 2;
Need to optimize query.
a number of things you need to check:
number of rows for each table. the more rows you have the slower it gets. Do you have the same size of data with UAT?
SELECT * : avoid the * and only retrieve columns you need.
ISNULL function on left side of the WHERE predicate will scan the index because it is non-sargable. you can check the answer here and rewrite your predicate without any function on the left side of WHERE clause.
You need to provide a detailed information like actual execution plan. I can only give you a generic answer because not much detail was provided.
Remember the UAT is very different in PROD. the hardware you used, the number of rows, etc..
Every advises in comment looks right. The difference between UAT and Prod should be the volume of data.
Your issue should come of lack or inefficient indices.
You should add compound index on
tblBrandDetails.CategoryId,tblBrandDetails.BrandId, tblBrandDetails.CityId
and on
tblBrandDetailUsers.CategoryId,tblBrandDetailUsers.BrandId, tblBrandDetailUsers.CityId
ensure that all unique ids have a btree index (or similar type of index depending on your DB)
You can also add conditional indices to filter quicker the null values:
https://www.brentozar.com/archive/2015/09/filtered-indexes-and-is-not-null/
Rewrite your query like this :
Select *--> AVOID "*" put all the necessary columns
from tblBrandDetailUsers AS tbdu
inner join tblBrands AS tbs on tbs.BrandId = tbdu.BrandId
left join tblBrandDetails AS tbd on tbd.CategoryId = tbdu.CategoryId
and tbd.BrandId = tbdu.BrandId
and tbd.CityId = tbdu.CityId
inner join tblCategory AS tc on tbdu.CategoryId = tc.CategoryId
inner join tblCity AS tcc on tcc.CityId = tbdu.CityId
where tbdu.SaleAmount <> tbd.SaleAmount
and tbdu.CityId = 3
and tbdu.TopLevelCategoryId = 2
UNION ALL
SELECT * --> AVOID "*" put all the necessary columns
from tblBrandDetailUsers AS tbdu
inner join tblBrands AS tbs on tbs.BrandId = tbdu.BrandId
left join tblBrandDetails AS tbd on tbd.CategoryId = tbdu.CategoryId
and tbd.BrandId = tbdu.BrandId
and tbd.CityId = tbdu.CityId
inner join tblCategory AS tc on tbdu.CategoryId = tc.CategoryId
inner join tblCity AS tcc on tcc.CityId = tbdu.CityId
where tbdu.SaleAmount IS NULL
AND tbd.SaleAmount IS NULL
and tbdu.CityId = 3
and tbdu.TopLevelCategoryId = 2;
Modify the SELECT clause to have only the necessary columns and not *
Be sure that you have index that are close to :
For tblBrandDetailUsers TABLE :
index KEY (CityId, TopLevelCategoryId, BrandId, CategoryId) INCLUDE (SaleAmount)
index KEY (CityId, TopLevelCategoryId, CategoryId) INCLUDE (SaleAmount)
For tblBrandDetails TABLE :
index (CityId, BrandId, CategoryId)
And also :
tblCategory (CategoryId)
tblCity (CityId)
tblBrands (BrandId)
When you will rectify the query especially the SELECT clause, we can give you more accurate indexes, because selected columns have a big weight on indexes performances !
as other suggested, try to add index on columns used for joins
I want to count my ReviewDetails.Review column but i got error:
Column 'AdvertiserMaster.AdvertiserID' is invalid in the select list
because it is not contained in either an aggregate function or the
GROUP BY clause.
Here Is My Query
SELECT DISTINCT
AdvertiserMaster.AdvertiserID, AdvertiserMaster.BusinessName , ISNULL(AdvertiserMaster.AverageRating, 0) AS AverageRating, AdvertiserMaster.ImageURL1, AdvertiserMaster.Address1,
AdvertiserMaster.CategoryID, AdvertiserMaster.Email, AdvertiserMaster.CountryID, AdvertiserMaster.StateID, AdvertiserMaster.CityID, AdvertiserMaster.PinCode, AdvertiserMaster.Mobile,
CategoryMaster.CategoryName, CountryMaster.CountryName, StateMaster.StateName, CityMaster.CityName,Count(ReviewDetails.Review) AS ReviewCount
FROM AdvertiserMaster INNER JOIN
BusinessCategoryDetails ON AdvertiserMaster.AdvertiserID = BusinessCategoryDetails.AdvertiserID INNER JOIN
ReviewDetails ON AdvertiserMaster.AdvertiserID = ReviewDetails.AdvertiserID LEFT OUTER JOIN
CategoryMaster ON AdvertiserMaster.CategoryID = CategoryMaster.CategoryID LEFT OUTER JOIN
CountryMaster ON AdvertiserMaster.CountryID = CountryMaster.CountryID LEFT OUTER JOIN
CityMaster ON AdvertiserMaster.CityID = CityMaster.CityID LEFT OUTER JOIN
StateMaster ON AdvertiserMaster.StateID = StateMaster.StateID LEFT OUTER JOIN
SubCategoryMaster ON BusinessCategoryDetails.SubCategoryID = SubCategoryMaster.SubCategoryID
WHERE (AdvertiserMaster.CategoryID = 8) AND (AdvertiserMaster.CityID = 16619) AND (AdvertiserMaster.IsActive = 1)
Since I am trying to get count by writing Count(ReviewDetails.Review)
But it is of no use.
here is my tables:ClassifiedBD Images
If you want to count something (or use other aggregate functions like sum), you need to define the level on which you count with group by clause, for example like this:
SELECT
AdvertiserMaster.AdvertiserID,
AdvertiserMaster.BusinessName,
ISNULL(AdvertiserMaster.AverageRating, 0) AS AverageRating,
AdvertiserMaster.ImageURL1,
AdvertiserMaster.Address1,
AdvertiserMaster.CategoryID,
AdvertiserMaster.Email,
AdvertiserMaster.CountryID,
AdvertiserMaster.StateID,
AdvertiserMaster.CityID,
AdvertiserMaster.PinCode,
AdvertiserMaster.Mobile,
CategoryMaster.CategoryName,
CountryMaster.CountryName,
StateMaster.StateName,
CityMaster.CityName,
COUNT(ReviewDetails.Review) AS ReviewCount
FROM AdvertiserMaster
INNER JOIN BusinessCategoryDetails
ON AdvertiserMaster.AdvertiserID = BusinessCategoryDetails.AdvertiserID
INNER JOIN ReviewDetails
ON AdvertiserMaster.AdvertiserID = ReviewDetails.AdvertiserID
LEFT OUTER JOIN CategoryMaster
ON AdvertiserMaster.CategoryID = CategoryMaster.CategoryID
LEFT OUTER JOIN CountryMaster
ON AdvertiserMaster.CountryID = CountryMaster.CountryID
LEFT OUTER JOIN CityMaster
ON AdvertiserMaster.CityID = CityMaster.CityID
LEFT OUTER JOIN StateMaster
ON AdvertiserMaster.StateID = StateMaster.StateID
LEFT OUTER JOIN SubCategoryMaster
ON BusinessCategoryDetails.SubCategoryID = SubCategoryMaster.SubCategoryID
WHERE (AdvertiserMaster.CategoryID = 8)
AND (AdvertiserMaster.CityID = 16619)
AND (AdvertiserMaster.IsActive = 1)
GROUP BY AdvertiserMaster.AdvertiserID,
AdvertiserMaster.BusinessName,
ISNULL(AdvertiserMaster.AverageRating, 0),
AdvertiserMaster.ImageURL1,
AdvertiserMaster.Address1,
AdvertiserMaster.CategoryID,
AdvertiserMaster.Email,
AdvertiserMaster.CountryID,
AdvertiserMaster.StateID,
AdvertiserMaster.CityID,
AdvertiserMaster.PinCode,
AdvertiserMaster.Mobile,
CategoryMaster.CategoryName,
CountryMaster.CountryName,
StateMaster.StateName,
CityMaster.CityName
You don't need distinct when you have group by.
You also might want to start using aliases for the tables and formatting / indenting your SQL properly
My recent project I have a requirements to print receivable summary. I need to return entire rows from the OpeningBalance table and matching rows from VoucherHeader and Customers.
My SQL query is this
SELECT
OpeningBalance.OpenID, Sum(OpeningBalance.Amount) AS SumOfAmount,
Sum(VoucherHeader.Debit) AS SumOfDebit, Sum(VoucherHeader.Credit) AS SumOfCredit,
Customers.CustomerID, Customers.CustomerName
FROM
(OpeningBalance
LEFT OUTER JOIN
VoucherHeader ON OpeningBalance.OpenID = VoucherHeader.LedgerID)
INNER JOIN
Customers ON OpeningBalance.OpenID = Customers.CustomerID
WHERE
(((Customers.CustomerType)='Debtor')
AND ((VoucherHeader.VoucherDate)<#2013/06/02#))
GROUP BY
OpeningBalance.OpenID, Customers.CustomerID, Customers.CustomerName,
VoucherHeader.LedgerID
ORDER BY
Customers.CustomerName;
Please help.
SELECT OB.OpenID, Sum(OB.Amount) AS SumOfAmount,
Sum(VB.Debit) AS SumOfDebit, Sum(VB.Credit) AS SumOfCredit, CS.CustomerID,
CS.CustomerName FROM OpeningBalance OB
LEFT OUTER JOIN VoucherHeader VB ON OB.OpenID = VB.LedgerID
LEFT OUTER JOIN Customers CS ON OB.OpenID = CS.CustomerID
WHERE (((CS.CustomerType)='Debtor') AND ((VB.VoucherDate)<#2013/06/02#))
GROUP BY OB.OpenID, CS.CustomerID, CS.CustomerName, VB.LedgerID
ORDER BY CS.CustomerName;