TSql: Trouble with join - sql-server

I am trying to write a join query but can't seem to filter it out. I'm selecting an invoice table and and applied payments table. I want to get the balance of all invoice totals amount - applied amounts. I can get the applied amounts fine using sum but when I try to get the total invoice amount, it is too high because its pulling multiple invoice results if more than one payment has been applied to it.
My results:
Invoice No | Amount | Paid
----------------------------
1 | 10 | 5
1 | 10 | 2
2 | 50 | 50
How do I select the sum invoice amount for unique invoice numbers?.
Query Overview:
Select sum(invoiceamount) - sum(appliedamount) as balance
FROM invoice
LEFT JOIN invoicepayments ON invoice.invoiceid = invoicepayments.invoiceid

You're actually looking for a very simple use of GROUP BY. You want to group every result that is the same Invoice/Amount, and then subtract the total (SUM) of the Paid column for that group from the Amount you are grouping on.
SELECT SUM(balance) FROM
(
SELECT invoiceamount - SUM(appliedamount) as balance
FROM invoice
GROUP BY invoiceid, invoiceamount
) balances

You can do it with CTE where you first calculate amount paid on each invoice and than join it to invoices to figure out what is left to pay for each invoice.
;WITH InvoicePay
AS (
SELECT invoiceid
,SUM(appliedamount) AS totalpaid
FROM invoicepayments
GROUP BY invoiceid
)
SELECT i.invoiceID
,i.invoiceamount - totalpaid as Balance
FROM Invoice AS i
JOIN InvoicePay AS ip
ON i.invoiceid = ip.invoiceid

Related

Joined tables - how to aggregate problem (sum)?

I have two tables joined like this:
SELECT count(DISTINCT T1.ContractNumber) AS nr_of_contracts,
count(T3.DateofInstallmentPayment) AS nr_of_paid_installents,
count(T3.DateofDueInstallment) AS nr_of_installments,
sum(T1.DisbursementAmount) AS disbursed_amount
FROM q.T1
LEFT JOIN q.T3
ON T1.ContractNumber=T3.ContractNumber
WHERE DateOfDisbursement BETWEEN '2019-12-01' AND '2019-12-31'
AND T3.DateofDueInstallment < GETDATE()
where T1 table contains data about clients (per contract number) and T3 about their payment schedules (per every instalment).
What I want is to have paid off amount (disbursement amount) of contracts from table T1 (aggregated by contract number) and not by every instalment. When I tried to select just sum(T1.Disbursement amount) then I receive sum but for all instalment which is incorrect.
T1:
Contract Number
DisbursementDate
Disbursement Amount
1
2019-12-01
1000
2
2019-12-01
2000
3
2019-12-01
3000
T3:
Contract Number
DateofDueInstallment
DateofInstallmentPayment
1
2020-01-01
2020-01-01
1
2020-02-01
2020-02-06
1
2020-03-01
2020-04-01
What I get after joining two tables for Contract Number = 1 is sum(DisbursementAmount) = 3000.
Contract Number
sum(DisbursementAmount)
1
3000
What I want after joining two tables for Contract Number = 1 is sum(DisbursementAmount) = 1000.
Contract Number
sum(DisbursementAmount)
1
1000
Something like this,not tested - a subquery with a different aggregation column
SELECT T1.product, T1.NrOfInstallment, count(DISTINCT T1.ContractNumber),
SELECT paid_amound FROM(SELECT ContractNumber, sum(tt.DisbursementAmount + (tt.ContractNumber*0.01))
- sum(tt.ContractNumber*0.01) as paid_amount
FROM abc.T1 as tt WHERE tt.ContractNumber = T1.ContractNumber GROUP BY ContractNumber) AS t)
FROM abc.T1
LEFT JOIN bde.T3
ON T1.ContractNumber=T3.ContractNumber
GROUP BY T1.product, T1.NrOfInstallment

Sql Server - Get SUM() of values for only Active Users

I have a requirement where i need to get Total Active Employees and Total Sales by RegionId
My query result should be like below.
RegionId | TotalEmployees | TotalSales | Average
1 10 100 10
2 3 15 5
My front end application will pass all the RegionIds as a single string separated by a comma, my query parameter is of type VARCHAR() and the Input paramter will look like '1,2,3,4,7,14,26' and there can be upto 20 Region Ids in a single string separated by a comma.
SELECT E.[RegionId] as RegionId
,COUNT(E.[EmployeeId) AS TotalEmployees
,(SELECT SUM([Sale])
FROM dbo.[Sales]
WHERE RegionId = R.[RegionId]
) AS TotalSales
,TotalSales/TotalEmployees AS Average
FROM dbo.[Employee]
JOIN [dbo].[ufn_StringSplit](#RegionIdCollection, ',') RegionId
ON E.RegionId = CAST(RegionId.[Data] AS Varchar(5000))
WHERE E.[Active] = 1
GROUP BY E.[RegionId]
My Employee table structures look alike below
EmployeeId | Name | RegionId | Active
100 Tom 2 1
101 Jim 4 0
103 Ben 2 1
Sales Table
SaleId | EmployeeId| RegionId | Sale
1 100 2 3500
2 101 4 2000
3 100 2 1500
Now my issue is when i am getting TotalSales the below query gets all the sales by RegionId, but i need to get All the sales done by only current Active employees in the Employee table
(SELECT SUM([Sale])
FROM dbo.[Sales]
WHERE RegionId = R.[RegionId]
) AS TotalSales
There is no reason to use a sub-select to find the sum of sales here, that will result in running that query for each and every row. You want to aproach this in a set based way which means you need to join and group appropriately:
with s as
(
select e.RegionId
,e.EmployeeId
,sum(s.Sale) as EmployeeSales
from dbo.ufn_StringSplit(#RegionIdCollection, ',') as r
join dbo.Employee as e
on r.RegionId = CAST(r.[Data] AS varchar(20)) -- Do you really need 5000 characters here?
left join dbo.Sales as s
on r.RegionId = s.RegionId
and e.EmployeeId = s.EmployeeId
where e.Active = 1
group by e.RegionId
,e.EmployeeId
)
select s.RegionId
,count(s.EmployeeId) as TotalEmployees
,sum(s.EmployeeSales) as TotalSales
,sum(s.EmployeeSales)/count(s.EmployeeId) as Average
from s
group by s.RegionId

Error on Group by method

I wrote a query to combine records in multiple tables. Tables named by Purchase Order, Purchase Order Item
[ Note: The column names are not original names, it just for a model data]
In purchase order table have the order details like this,
id date vendorid totalitems totalqty grossamnt netamnt taxamt
----------------------------------------------------------------------------
1 03/10/17 00001 2 6 12000 13000 1000
Purchase Order Item table have the order details like this,
poid id productcode qty rate tax(%) taxamnt total
--------------------------------------------------------
1 1 12001 3 6000 2.5 500 6500
2 1 12000 3 6000 2.5 500 6500
My Query is,
select po.POID,po.SupplierId,po.TotalItems from
PurchaseOrder po, PurchaseOrderItem poi where po.POID=poi.POID group by
po.POID, po.SupplierId,po.TotalItems
Query returns,
id vendorid totalitems
--------------------------
1 00001 2
1 00001 2
Expected Output is,
id vendorid totalitems
------------------------
1 00001 2
You are using an outdated join method, have a read here:
ANSI vs. non-ANSI SQL JOIN syntax
You are also joining to another table, but never use it:
select po.POID,po.SupplierId,po.TotalItems
from PurchaseOrder po, PurchaseOrderItem poi
where po.POID=poi.POID
group by po.POID, po.SupplierId,po.TotalItems
Can just be:
select po.POID,po.SupplierId,po.TotalItems
from PurchaseOrder po
group by po.POID, po.SupplierId,po.TotalItem
OR
select DISTINCT
po.POID,
po.SupplierId,
po.TotalItems
from PurchaseOrder po

Filter two table rows by using group by with join in SQL Server

I have two tables as Sales and SalesDocument.
Sales Table
RequestId(PrimaryKey) ReqType DateTime
--------- ------- --------
1 Buy 22/10/2015
2 Buy 03/11/2015
3 Sell 10/11/2015
4 Return 11/12/2015
6 Sell 11/12/2015
7 Buy 20/12/2015
Sales Document Table
RequestId(Ref.Key(FK)) ReqDocument ReqDocURL
--------- ----------- ---------
2 Doc1 Http://..Doc1.PDF
3 Doc2 Http://..Doc2.PDF
3 Doc3 Http://..Doc3.PDF
4 Doc1 Http://..Doc1.PDF
4 Doc2 Http://..Doc2.PDF
4 Doc3 Http://..Doc3.PDF
6 Doc2 Http://..Doc2.PDF
6 Doc3 Http://..Doc3.PDF
Now I need to select the records in both tables by using RequestId(as Ref.Key) and the condition are,
1)In 1st Table,Need to get distinct ReqType(FirstColumn:RequestType) and It's count(SecondColumn:RequestTypeCount) based between two date ranges.
2)In 2nd Table, Need to calculate total no.of requested documents(ThirdColumn:SumOfReqDocument) by using RequestType(RequestType is not in 2nd table, hence we need to map with 1st table(sales) by RequestId and get the sum of documents.
The output should be,
RequestType RequestTypeCount SumOfReqDocument
----------- ---------------- ----------------
Buy 3 1
Sell 2 4
Return 1 3
I tried some SQL query but it does not result the actual result. Please help me on this SQL query\Suggest me some other query.
My Query is,
SELECT ReqType as RequestType,count(ReqType) as RequestTypeCount,count(salesDoc.DocumentURL) as SumOfReqDocument FROM Sales sales inner join SalesDocument salesDoc on
sales.RequestId=salesDoc.RequestId where sales.EndDate >= '2015-10-22 10:34:09.000' AND sales.EndDate <= '2015-12-31 00:00:00.000'
group by sales.ReqType
You may try change the INNER JOIN to LEFT JOIN, and COUNT DISTINCT ReqestID for RequestTypeCount
SELECT ReqType as RequestType
,count(DISTINCT sales.RequestId) as RequestTypeCount
,count(salesDoc.ReqDocURL) as SumOfReqDocument
FROM Sales sales
LEFT JOIN SalesDocument salesDoc
ON sales.RequestId=salesDoc.RequestId
WHERE sales.EndDate >= '2015-10-21 10:34:09.000' AND sales.EndDate <= '2015-12-31 00:00:00.000'
group by sales.ReqType

Query to get sum of an employees commission

Query to get total commissions for an employee, and update their totalCommission column in the employee table.
This query is run every few days (batch).
The rules:
1. an employee can only get a maximum of $100/day of commision, if they get more than $100 it just gets set to $100.
Tables:
Employee
(employeeID INT PK, totalCommissions INT, username, ...)
Sale
(saleID INT PK, employeeID INT FK, saleTotal, commission, created DATETIME)
Using SQL Server 2005.
So this query will have to group by day I presume, and use a case statement to set the daily commision to $100 if the sum is > 100 for that day, and then set the total SUM for all days to the Employee.TotalCommission column.
assuming you are limiting the dates somewhere using value of "somedate-goes-here":
update employee set totalcommissions = totalc
from
(
-------------------------------------
-- sum capped commissions by employee
-------------------------------------
select employeeID, sum(sum_commissions) as totalc from
(
---------------------------------------
-- make sure sum is capped if necessary
---------------------------------------
select employeeID
, case when sum_of_c > 100 then 100 else sum_of_c as sum_commisions
from
(
-----------------------------------------------
-- get sum of commissions per day per employee
-----------------------------------------------
select employeeID, sum(commission) as sum_of_c from sale
where created > "somedate-goes-here"
group by employeeID, day(created)
) as x
) as c
group by employeeID
) y
inner join employee on employee.employeeID = y.employeeID

Resources